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())
}
Exemple #2
0
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
}