func (this *Connection) Loop(waitGroup *sync.WaitGroup) { // AFTER THIS ALL THE MESSAGE USING AES this.contex.EncryptType = common.ZC_SEC_TYPE_AES this.contex.SessionKey = this.sessionKey // process write queue in the new routine waitGroup.Add(1) go func() { // request packet var requestPacket common.Message for !this.exit { select { case requestPacket = <-this.requestQueue: // write the packet to read queue fmt.Println("[DEV] send the new Request Message to device:", requestPacket.Header.MsgId) err := common.Send(this.socket, this.contex, &requestPacket, common.DEV_WRITE_TIMEOUT) if err != nil { log.Warningf("forward the packet failed:err[%v]", err) this.exit = true break } // wait the empty response for the requestPacket // if not wait empty succ, can not send the next request // from the requestQueue.... this.waitEmptyResponse(&requestPacket) fmt.Println("[DEV] wait Empty Response succ:", requestPacket.Header.MsgId) } } log.Infof("forward device request routine exit:dest[%v]", this.socket.RemoteAddr()) waitGroup.Done() }() // process the read empty or response or report message var devMessage common.Message for !this.exit { // read the packet and dispatch to the processor err := common.Receive(this.socket, this.contex, &devMessage, common.DEV_READ_TIMEOUT) if err != nil { log.Warningf("read the packet failed:dest[%v], err[%v]", this.socket.RemoteAddr(), err) this.exit = true break } fmt.Println("[DEV] Receive message from device succ", devMessage.Header.String()) // TODO if too long not receive dev message, close it // Handle Dev Message three different type // repsonse Ack + response Empty + request Report // WARNING:can not blocked here... this.handleDevMessage(&devMessage) fmt.Println("[DEV] Handle dev message finish:", time.Now().UTC(), devMessage.Header, this.socket.RemoteAddr()) } log.Infof("device routine exit succ:dest[%v], gid[%s]", this.socket.RemoteAddr(), this.gid.String()) }
func loop() { //conn, err := net.Dial("tcp", "101.251.106.4:8384") //conn, err := net.Dial("tcp", "127.0.0.1:8384") conn, err := net.Dial("tcp", "192.168.1.114:8384") if err != nil { fmt.Println("Connect Error:", err) return } defer conn.Close() body := make([]byte, 1024) var report, request, response, empty common.Message // handshake step 1 randKey := common.GenerateRandomKey(common.ZC_HS_MSG_LEN) request.Header.MsgCode = common.ZC_CODE_HANDSHAKE_1 request.Header.PayloadLen = common.ZC_HS_MSG_LEN + common.ZC_HS_DEVICE_ID_LEN deviceId := "zzzzzzzzzzzz" fmt.Println("Generate random and id:", randKey, []byte(deviceId)) request.Payload = make([]byte, request.Header.PayloadLen) copy(request.Payload[0:common.ZC_HS_MSG_LEN], randKey) copy(request.Payload[common.ZC_HS_MSG_LEN:request.Header.PayloadLen], []byte(deviceId)) var contex common.EncryptContex contex.PublicKey = []byte("80138512665003396643737838315916663972728479914654754587175091902061894104953") contex.EncryptType = common.ZC_SEC_TYPE_RSA err = common.Send(conn, contex, &request, common.DEV_WRITE_TIMEOUT) if err != nil { fmt.Println("HANDSHAKE_1 failed:", err) return } fmt.Println("Write Handshake_1 succ") // handshake step 2 contex.PrivateKey = common.PrivateKey err = common.Receive(conn, contex, &response, common.DEV_READ_TIMEOUT) if err != nil { fmt.Println("HANDSHAKE_2 failed:", err) return } sessionKey := make([]byte, common.ZC_HS_SESSION_KEY_LEN) copy(sessionKey, response.Payload[common.ZC_HS_MSG_LEN:]) fmt.Println("Receive Handshake_2 Session Key:", response.Payload[:common.ZC_HS_MSG_LEN], sessionKey) // handshake step 3 contex.EncryptType = common.ZC_SEC_TYPE_AES contex.SessionKey = sessionKey copy(request.Payload, randKey) request.Payload = request.Payload[0:common.ZC_HS_MSG_LEN] request.Header.PayloadLen = common.ZC_HS_MSG_LEN if len(request.Payload) != int(request.Header.PayloadLen) { fmt.Println("check payload len failed", len(request.Payload), request.Header.PayloadLen) return } request.Header.MsgCode = common.ZC_CODE_HANDSHAKE_3 err = common.Send(conn, contex, &request, common.DEV_WRITE_TIMEOUT) if err != nil { fmt.Println("HANDSHAKE_3 failed:", err) return } fmt.Println("Write Handshake_3 succ") // handshake step 4 err = common.Receive(conn, contex, &response, common.DEV_READ_TIMEOUT) if err != nil { fmt.Println("HANDSHAKE_4 failed:", err) return } else if !bytes.Equal(response.Payload, randKey) { fmt.Println("check random key failed") return } else { fmt.Println("CLOUD SAY HELLO WORLD TO DEV") } for i := 0; i < 3600; i++ { // step 1. send report message report.Header.PayloadLen = 0 report.Header.Version = 123 report.Header.MsgCode = common.ZC_CODE_HEARTBEAT report.Header.MsgId = uint8(i + 101) report.Payload = body[:report.Header.PayloadLen] err = common.Send(conn, contex, &report, common.DEV_WRITE_TIMEOUT) if err != nil { fmt.Println("Write Report Error:", err) return } // step 2. read the request err = common.Receive(conn, contex, &request, common.DEV_READ_TIMEOUT) if err != nil { fmt.Println("Receive Response Error:", err) return } fmt.Println("Read Request succ:", request.Header.MsgId, request.Payload) // step 3. echo empty message empty.Header.MsgId = request.Header.MsgId empty.Header.Version = request.Header.Version empty.Header.MsgCode = common.ZC_CODE_EMPTY empty.Header.PayloadLen = 0 err = common.Send(conn, contex, &empty, common.DEV_WRITE_TIMEOUT) if err != nil { fmt.Println("Write Empty Response failed:", err) return } // fmt.Println("Write Empty Response", request.Header.MsgId) // step 4. write echo ack request.Header.MsgCode = common.ZC_CODE_ACK err = common.Send(conn, contex, &request, common.DEV_WRITE_TIMEOUT) if err != nil { fmt.Println("Write Response failed:", err) return } fmt.Println("Write Response:", request.Header.MsgId, request.Payload) } }
func (this *Connection) DeviceHandShake() (*DeviceGID, error) { var handShake common.Message // HANDSHAKE_1 using cloud private key this.contex.EncryptType = common.ZC_SEC_TYPE_RSA this.contex.PrivateKey = common.PrivateKey err := common.Receive(this.socket, this.contex, &handShake, common.DEV_READ_TIMEOUT) if err != nil { log.Warningf("read handShake_1 failed:err[%v]", err) return nil, err } else if handShake.Header.MsgCode != common.ZC_CODE_HANDSHAKE_1 { log.Warningf("check message code failed:code[%d]", handShake.Header.MsgCode) return nil, common.ErrInvalidMsg } else if handShake.Header.PayloadLen != (common.ZC_HS_MSG_LEN + common.ZC_HS_DEVICE_ID_LEN) { log.Warningf("check handshake step 1 failed:len[%d]", handShake.Header.PayloadLen) return nil, common.ErrInvalidMsg } fmt.Println("[DEV] HANDSHAKE_1 SUCC") // get device public key for rsa devRandom := handShake.Payload[0:common.ZC_HS_MSG_LEN] deviceId := handShake.Payload[common.ZC_HS_MSG_LEN : common.ZC_HS_MSG_LEN+common.ZC_HS_DEVICE_ID_LEN] log.Infof("Receive Dev Random and ID:", devRandom, deviceId) this.gid = DeviceGID{domain: "app", subDomain: "test", deviceId: string(deviceId)} device, err := this.deviceManager.Get(this.gid) if err != nil { log.Errorf("the device not valid:addr[%v], gid[%s]", this.socket.RemoteAddr(), this.gid.String()) return nil, err } // HANDSHAKE_2 using device public key this.contex.EncryptType = common.ZC_SEC_TYPE_RSA this.contex.PublicKey = []byte(device.PublicKey()) this.sessionKey = common.GenerateRandomKey(common.ZC_HS_SESSION_KEY_LEN) log.Infof("New session key:key[%v], dest[%v], gid[%s]", this.sessionKey, this.socket.RemoteAddr(), this.gid.String()) handShake.Header.MsgId = this.getNewRequestId() var response common.Message response.Header.MsgCode = common.ZC_CODE_HANDSHAKE_2 response.Header.PayloadLen = common.ZC_HS_MSG_LEN + common.ZC_HS_SESSION_KEY_LEN response.Payload = make([]byte, response.Header.PayloadLen) copy(response.Payload[0:common.ZC_HS_MSG_LEN], devRandom) copy(response.Payload[common.ZC_HS_MSG_LEN:response.Header.PayloadLen], this.sessionKey) err = common.Send(this.socket, this.contex, &response, common.DEV_WRITE_TIMEOUT) if err != nil { log.Warningf("Write ZC_CODE_HANDSHAKE_2 failed:err[%v]", err) return &this.gid, err } fmt.Println("[DEV] HANDSHAKE_2 SUCC") // HANDSHAKE_3 using session key this.contex.EncryptType = common.ZC_SEC_TYPE_AES this.contex.SessionKey = this.sessionKey err = common.Receive(this.socket, this.contex, &handShake, common.DEV_READ_TIMEOUT) if err != nil { log.Warningf("read handShake_3 failed:err[%v]", err) return &this.gid, err } else if handShake.Header.MsgCode != common.ZC_CODE_HANDSHAKE_3 { log.Warningf("check message code failed:code[%d]", handShake.Header.MsgCode) return &this.gid, common.ErrInvalidMsg } else if handShake.Header.PayloadLen != common.ZC_HS_MSG_LEN { log.Warningf("check handshake step 3 failed:len[%d]", handShake.Header.PayloadLen) return &this.gid, common.ErrInvalidMsg } else if !bytes.Equal(handShake.Payload, devRandom) { log.Warningf("check handshake content failed:payload[%v], random[%v]", handShake.Payload, devRandom) return &this.gid, common.ErrInvalidMsg } fmt.Println("[DEV] HANDSHAKE_3 SUCC") // HANDSHAKE_4 using session key this.contex.EncryptType = common.ZC_SEC_TYPE_AES this.contex.SessionKey = this.sessionKey handShake.Header.MsgId = this.getNewRequestId() handShake.Header.MsgCode = common.ZC_CODE_HANDSHAKE_4 handShake.Header.PayloadLen = common.ZC_HS_MSG_LEN handShake.Payload = devRandom err = common.Send(this.socket, this.contex, &handShake, common.DEV_WRITE_TIMEOUT) if err != nil { log.Warningf("Write ZC_CODE_HANDSHAKE_4 failed:err[%v]", err) return &this.gid, err } fmt.Println("[DEV] HANDSHAKE_4 PASS, WELCOME:", this.socket.RemoteAddr()) return &this.gid, err }