From 4444beaf983881ab390760bde06ebae91cb59d88 Mon Sep 17 00:00:00 2001 From: Tomek Osika Date: Sat, 11 Nov 2023 14:27:05 +0100 Subject: [PATCH 1/2] link device in json-rpc mode --- src/client/client.go | 54 +++++++++++++++++++++++++++++++++++++++++- src/client/jsonrpc2.go | 25 +++++++++---------- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/src/client/client.go b/src/client/client.go index f37f491a..fabcb27b 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + log "github.com/sirupsen/logrus" "io/ioutil" "os" "path/filepath" @@ -1053,7 +1054,58 @@ func (s *SignalClient) DeleteGroup(number string, groupId string) error { func (s *SignalClient) GetQrCodeLink(deviceName string, qrCodeVersion int) ([]byte, error) { if s.signalCliMode == JsonRpc { - return []byte{}, errors.New(endpointNotSupportedInJsonRpcMode) + jsonRpc2Client, err := s.getJsonRpc2Client() + if err != nil { + return []byte{}, err + } + + type StartRequest struct{} + type Response struct { + DeviceLinkUri string `json:"deviceLinkUri"` + } + + result, err := jsonRpc2Client.getRaw("startLink", nil, &StartRequest{}) + if err != nil { + return []byte{}, errors.New("Couldn't create QR code: " + err.Error()) + } + + var resp Response + err = json.Unmarshal([]byte(result), &resp) + if err != nil { + return []byte{}, errors.New("Couldn't create QR code: " + err.Error()) + } + + q, err := qrcode.NewWithForcedVersion(string(resp.DeviceLinkUri), qrCodeVersion, qrcode.Highest) + if err != nil { + return []byte{}, errors.New("Couldn't create QR code: " + err.Error()) + } + + var png []byte + png, err = q.PNG(256) + if err != nil { + return []byte{}, errors.New("Couldn't create QR code: " + err.Error()) + } + + go (func() { + type FinishRequest struct { + DeviceLinkUri string `json:"deviceLinkUri"` + DeviceName string `json:"deviceName"` + } + + req := FinishRequest{ + DeviceLinkUri: resp.DeviceLinkUri, + DeviceName: deviceName, + } + + result, err := jsonRpc2Client.getRaw("finishLink", nil, &req) + if err != nil { + log.Debug("Error linking device: ", err.Error()) + return + } + log.Debug("Linking device result: ", result) + })() + + return png, nil } command := []string{"--config", s.signalCliConfig, "link", "-n", deviceName} diff --git a/src/client/jsonrpc2.go b/src/client/jsonrpc2.go index e614a8f6..e6191a0a 100644 --- a/src/client/jsonrpc2.go +++ b/src/client/jsonrpc2.go @@ -32,17 +32,18 @@ type JsonRpc2ReceivedMessage struct { type JsonRpc2Client struct { conn net.Conn - receivedMessageResponses chan JsonRpc2MessageResponse + receivedResponsesById map[string]chan JsonRpc2MessageResponse receivedMessages chan JsonRpc2ReceivedMessage lastTimeErrorMessageSent time.Time signalCliApiConfig *utils.SignalCliApiConfig - number string + number string } func NewJsonRpc2Client(signalCliApiConfig *utils.SignalCliApiConfig, number string) *JsonRpc2Client { return &JsonRpc2Client{ - signalCliApiConfig: signalCliApiConfig, - number: number, + signalCliApiConfig: signalCliApiConfig, + number: number, + receivedResponsesById: make(map[string]chan JsonRpc2MessageResponse), } } @@ -53,7 +54,6 @@ func (r *JsonRpc2Client) Dial(address string) error { return err } - r.receivedMessageResponses = make(chan JsonRpc2MessageResponse) r.receivedMessages = make(chan JsonRpc2ReceivedMessage) return nil @@ -113,13 +113,12 @@ func (r *JsonRpc2Client) getRaw(command string, account *string, args interface{ return "", err } + responseChan := make(chan JsonRpc2MessageResponse) + r.receivedResponsesById[u.String()] = responseChan + var resp JsonRpc2MessageResponse - for { - resp = <-r.receivedMessageResponses - if resp.Id == u.String() { - break - } - } + resp = <-responseChan + delete(r.receivedResponsesById, u.String()) if resp.Err.Code != 0 { return "", errors.New(resp.Err.Message) @@ -157,7 +156,9 @@ func (r *JsonRpc2Client) ReceiveData(number string) { err = json.Unmarshal([]byte(str), &resp2) if err == nil { if resp2.Id != "" { - r.receivedMessageResponses <- resp2 + if responseChan, ok := r.receivedResponsesById[resp2.Id]; ok { + responseChan <- resp2 + } } } else { log.Error("Received unparsable message: ", str) From 3ea7949c104e573ed44d0b6487f2e1bb6e6cf237 Mon Sep 17 00:00:00 2001 From: Tomek Osika Date: Sat, 11 Nov 2023 22:23:26 +0100 Subject: [PATCH 2/2] also reload config after device was linked successfully --- src/client/client.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/client/client.go b/src/client/client.go index fabcb27b..071f9477 100644 --- a/src/client/client.go +++ b/src/client/client.go @@ -1103,6 +1103,7 @@ func (s *SignalClient) GetQrCodeLink(deviceName string, qrCodeVersion int) ([]by return } log.Debug("Linking device result: ", result) + s.signalCliApiConfig.Load(s.signalCliApiConfigPath) })() return png, nil