Esempio n. 1
0
 def _decode(raw_value: bytes) -> Tuple[float, Quality]:
     raw_value, _ = raw_value
     if len(raw_value) != 8:
         raise ValueError('raw_value out of supported length')
     seconds = s_unpack('!I', raw_value[:4])[0]
     # TODO Fraction seems to be wrong
     fraction = s_unpack('!I', b'\x00' + raw_value[4:7])[0]
     quality = Quality(raw_value=raw_value[7:8])
     return float(str(f'{seconds}.{fraction}')), quality
Esempio n. 2
0
 def _decode(raw_value: bytes) -> int:
     if len(raw_value) == 1:
         return s_unpack('!b', raw_value)[0]
     elif len(raw_value) == 2:
         return s_unpack('!h', raw_value)[0]
     elif len(raw_value) == 4:
         return s_unpack('!i', raw_value)[0]
     elif len(raw_value) == 8:
         return s_unpack('!q', raw_value)[0]
     raise ValueError('Signed integer out of supported range')
Esempio n. 3
0
 def _decode(raw_value: bytes) -> int:
     if len(raw_value) == 1:
         return s_unpack('!B', raw_value)[0]
     elif len(raw_value) == 2:
         return s_unpack('!H', raw_value)[0]
     # elif len(raw_value) == 3:
     #     # NOTE regular MMS does not have 24 bits unsigned int
     #     # NOTE 24 bits unsigned int seems to be used only for timestamp
     #     return s_unpack('!I', b'\x00' + raw_value)[0]
     elif len(raw_value) == 4:
         return s_unpack('!I', raw_value)[0]
     raise ValueError('Unsigned integer out of supported range')
Esempio n. 4
0
 def unpack(self, bytearray):
     lower_offset = 0
     upper_offset = 0
     # unpack pressure
     upper_offset += 8
     bytes = bytearray[lower_offset:upper_offset]
     lower_offset = upper_offset
     self.pressure = s_unpack("d", bytes)[0]
     # unpack temperature
     upper_offset += 8
     bytes = bytearray[lower_offset:upper_offset]
     lower_offset = upper_offset
     self.temperature = s_unpack("d", bytes)[0]
Esempio n. 5
0
 def process_response(self):
     """
     gevent读事件的监听回调处理,用于读取数据
     """
     try:
         now_data = self._recv(8192)
         if not now_data:                             # 如果读取的数据为空,那么socket已经断开了
             self.close()
             return
     except:
         ex = sys.exc_info()[1]                       # 获取异常对象
         error_no = ex.args[0]                        # 获取错误代码
         sys.exc_clear()                              # 当前是在主协程中运行,这里直接清理掉异常信息
         if error_no not in (EWOULDBLOCK, EAGAIN):
             self.close()                             # 一般情况下是一些reset关闭啥的
         return                                       # 根本就没有数据可以处理,还搞毛啊,直接返回
     self._now_data += now_data                       # 将读取的数据保存起来
     self._recv_ping_time = 0                         # 重置心跳标志为
     while 1:
         if self._status == 1 and len(self._now_data) >= 4:         # 当前状态还需要读取数据的头部
             body_len_data = self._now_data[:4]                     # 获取4个字节长度的头部
             self._body_len, = s_unpack("i", body_len_data)         # 计算数据body应该有的长度
             self._now_data = self._now_data[4:]                    # 将4个字节的头部从数据中移除
             if self._body_len == -1:                               # 这里如果数据包的长度为-1,那么就是心跳数据
                 continue                                           # 这里直接略过
             self._status = 2                                       # 更改状态标志
         elif self._status == 2 and len(self._now_data) >= self._body_len:
             response_data = self._now_data[:self._body_len]        # 这个就是客户端发送过来的数据
             self._now_data = self._now_data[self._body_len:]       # 将输入数据清除
             self._status = 1                                       # 恢复状态标志为
             rid, message = cp_loads(response_data)
             if rid in self._events:                                # 找到当前返回数据对应的event
                 self._events[rid].set(message)                     # 找到对应挂起的事件,然后设置,唤醒挂起的协程
         else:
             break
Esempio n. 6
0
 def unpack(self,bytearray):
    lower_offset = 0
    upper_offset = 0
    # unpack accx
    upper_offset += 8
    bytes = bytearray[lower_offset:upper_offset]
    lower_offset = upper_offset
    self.accx = s_unpack("d",bytes)[0]
    # unpack accy
    upper_offset += 8
    bytes = bytearray[lower_offset:upper_offset]
    lower_offset = upper_offset
    self.accy = s_unpack("d",bytes)[0]
    # unpack accz
    upper_offset += 8
    bytes = bytearray[lower_offset:upper_offset]
    lower_offset = upper_offset
    self.accz = s_unpack("d",bytes)[0]
Esempio n. 7
0
 def unpack(self,bytearray):
    lower_offset = 0
    upper_offset = 0
    # unpack position
    upper_offset += self.position.getSize()
    bytes = bytearray[lower_offset:upper_offset]
    lower_offset = upper_offset
    self.position.unpack(bytes)
    # unpack age
    upper_offset += 8
    bytes = bytearray[lower_offset:upper_offset]
    lower_offset = upper_offset
    self.age = s_unpack("Q",bytes)[0]
    # unpack sats
    upper_offset += 2
    bytes = bytearray[lower_offset:upper_offset]
    lower_offset = upper_offset
    self.sats = s_unpack("h",bytes)[0]
Esempio n. 8
0
 def unpack(self, bytearray):
     lower_offset = 0
     upper_offset = 0
     # unpack lat
     upper_offset += 8
     bytes = bytearray[lower_offset:upper_offset]
     lower_offset = upper_offset
     self.lat = s_unpack("d", bytes)[0]
     # unpack lon
     upper_offset += 8
     bytes = bytearray[lower_offset:upper_offset]
     lower_offset = upper_offset
     self.lon = s_unpack("d", bytes)[0]
     # unpack alt
     upper_offset += 4
     bytes = bytearray[lower_offset:upper_offset]
     lower_offset = upper_offset
     self.alt = s_unpack("f", bytes)[0]
Esempio n. 9
0
 def unpack(self, octets):
     '''Return a 2-tuple (val, octets), the value unpacked from binary string `octets`, and the
        trailing octets not unpacked, respectively. If :attr:`sfmt` is None then this method MUST
        be overridden. Raise :class:`ValueError` or :class:`TypeError` if a value of this type
        cannot be unpacked from `octets`.
     '''
     if self.sfmt is None:
         raise NotImplementedError()
     sfmt = '>' + self.sfmt
     return (s_unpack(sfmt, octets)[0], octets[s_size(sfmt):])
Esempio n. 10
0
    def _decode(self, raw_value: bytes) -> Tuple[bool, bool, bool, int]:
        if not isinstance(raw_value, bytes):
            raise_type('raw_value', bytes, type(raw_value))
        if len(raw_value) != 1:
            raise ValueError('raw_value out of supported length')

        bits = s_unpack('!B', raw_value)[0]

        time_accuracy = bits & 0x1F
        if time_accuracy > 24 and time_accuracy != 0x1F:
            raise ValueError('bits out of supported range')

        leap_seconds_known = (bits & 0x80) == 0x80
        clock_failure = (bits & 0x40) == 0x40
        clock_not_synchronized = (bits & 0x20) == 0x20

        return leap_seconds_known, clock_failure, clock_not_synchronized, time_accuracy
Esempio n. 11
0
    def unpack(self, fmt):
        """Unpack wrapper for automatic extraction of given format

        Arguments:
        fmt - Format of bytes to read (see struct.unpack)"""
        from struct import calcsize, unpack as s_unpack

        fmt_size = calcsize(fmt)
        data = self.read(fmt_size)
        if len(data) != fmt_size:
            exception = "Format mismatch: Tried to unpack {} bytes but got {}"
            raise IOError(exception.format(fmt_size, len(data)))

        ret = s_unpack(fmt, data)
        if len(ret) == 1:
            return ret[0]
        return ret
Esempio n. 12
0
    def process(self):
        """
        因为启动了当前socket的读监听,所以在有数据可以读取的时候,会调用这个方法来处理
        这里要做的事情就是读取出来数据然后处理

        注意:因为这个回调直接就是watcher的回调,是在loop协程上运行的,不能够阻塞loop协程,所以
            数据包解析出来之后服务的调用都需要派发到别的协程中运行
        注意:这里并没有不断的读取数据直到将数据全部读取完,因为默认水平触发,这样子可以降低一些recv系统调用的次数
        """
        try:
            now_data = self._recv(8192)              # 这里直接从底层的socket读取数据
            if not now_data:                         # 如果读取的数据为空,那么socket已经断开了
                self.close()                         # 关闭当前的连接
                return
        except:
            ex = sys.exc_info()[1]                       # 获取异常对象
            error_no = ex.args[0]                        # 错误号码
            sys.exc_clear()                              # 当前是在主协程中运行,这里直接清理掉异常信息
            if error_no not in (EWOULDBLOCK, EAGAIN):    # 这里判断一下是不是正常的异常情况
                self.close()                             # 一般情况下是一些reset关闭啥的
            return                                       # 根本就没有数据可以处理,直接返回
        self._now_data += now_data                       # 将刚刚收到的数据拼起来
        self._recv_ping_time = 0                         # 只要有数据来了就可以将心跳标志为设置为0了
        while 1:
            if self._status == 1 and len(self._now_data) >= HEAD_LEN:          # 当前为接收header的状态
                body_len_data = self._now_data[0:HEAD_LEN]                     # 获取头部数据
                self._body_len, = s_unpack("i", body_len_data)                 # 相应数据的body的长度
                self._now_data = self._now_data[HEAD_LEN:]                     # 将头部数据移除
                if self._body_len == -1:                                       # 心跳包,长度直接为-1
                    continue                                                   # 心跳数据
                self._status = 2                                               # 更改状态标志,接下来读取body
            elif self._status == 2 and len(self._now_data) >= self._body_len:  # 读取body的数据
                input_data = self._now_data[0:self._body_len]                  # 这个就是客户端发送过来的数据
                self._now_data = self._now_data[self._body_len:]               # 将输入数据清除
                self._status = 1                                               # 恢复状态标志为,下次就再次读取头部
                """
                注意:因为python本身并没有段作用域这种事说法,所以在构建异步执行的时候一定要非常小心
                     如果在异步执行的任务中直接引用外部闭包的变量,有可能会有一致性的问题,尤其是在循环内部,
                     外部的闭包变量可能已经更改,等到异步执行的时候,它所引用的变量也就更改了,从而导致
                     逻辑上的不正确

                     这里解决方案就是直接造再重新构建一层闭包,将外部变量重新包到新的闭包环境中去
                """
                run_task(self._generate_task(input_data))                      # 将任务派发到协程池中运行
            else:
                break                                                          # 数据还无法处理,那么跳出循环
Esempio n. 13
0
 def process_response(self):
     """
     gevent读事件的监听回调处理,用于读取数据
     """
     try:
         now_data = self._recv(8192)
         if not now_data:  # 如果读取的数据为空,那么socket已经断开了
             self.close()
             return
     except:
         ex = sys.exc_info()[1]  # 获取异常对象
         error_no = ex.args[0]  # 获取错误代码
         sys.exc_clear()  # 当前是在主协程中运行,这里直接清理掉异常信息
         if error_no not in (EWOULDBLOCK, EAGAIN):
             self.close()  # 一般情况下是一些reset关闭啥的
         return  # 根本就没有数据可以处理,还搞毛啊,直接返回
     self._now_data += now_data  # 将读取的数据保存起来
     self._recv_ping_time = 0  # 重置心跳标志为
     while 1:
         if self._status == 1 and len(
                 self._now_data) >= 4:  # 当前状态还需要读取数据的头部
             body_len_data = self._now_data[:4]  # 获取4个字节长度的头部
             self._body_len, = s_unpack("i",
                                        body_len_data)  # 计算数据body应该有的长度
             self._now_data = self._now_data[4:]  # 将4个字节的头部从数据中移除
             if self._body_len == -1:  # 这里如果数据包的长度为-1,那么就是心跳数据
                 continue  # 这里直接略过
             self._status = 2  # 更改状态标志
         elif self._status == 2 and len(self._now_data) >= self._body_len:
             response_data = self._now_data[:self.
                                            _body_len]  # 这个就是客户端发送过来的数据
             self._now_data = self._now_data[self._body_len:]  # 将输入数据清除
             self._status = 1  # 恢复状态标志为
             rid, message = cp_loads(response_data)
             if rid in self._events:  # 找到当前返回数据对应的event
                 self._events[rid].set(message)  # 找到对应挂起的事件,然后设置,唤醒挂起的协程
         else:
             break
Esempio n. 14
0
    def handle(self):
        try:
            self.update_status()

            while self.status not in (self.CONNECTION_END,
                                      self.CONNECTION_STOP):
                try:
                    data_size = self.rfile.read(4)
                except timeout:
                    self.update_status()
                    print self.status
                else:
                    break

            self.update_status()

            while self.status not in (self.CONNECTION_END,
                                      self.CONNECTION_STOP):
                if len(data_size) < 4:
                    print 'Wrong input received: EOF while waiting for \
message length (4 bytes long)'

                    self.update_status(self.CONNECTION_STOP)
                else:
                    data_size = s_unpack('!I', data_size)[0]
                    if data_size > 4096:
                        print 'Wrong input received: message size exceeds \
4096 bytes'

                        self.update_status(self.CONNECTION_STOP)
                    else:
                        try:
                            data = self.rfile.read(data_size)
                        except timeout:
                            print 'Wrong input received: timeout'
                            self.update_status(self.CONNECTION_STOP)
                        else:
                            if len(data) < data_size:
                                print 'Wrong input received: EOF while \
waiting message content (' + str(data_size) + '\nbytes long)'
                                self.update_status(self.CONNECTION_STOP)
                            else:
                                try:
                                    data = m_unpack(data, use_list=False)
                                except Exception as exception:
                                    print 'Wrong input received:', exception
                                    self.update_status(self.CONNECTION_STOP)
                                else:
                                    self.handle_test(data)
                                    try:
                                        handler_suffix = data['type']
                                    except TypeError:
                                        print "Wrong input received: invalid \
message's type"

                                        self.update_status(
                                            self.CONNECTION_STOP)
                                    except KeyError:
                                        print 'Wrong input received: no \
`type` field in message'

                                        self.update_status(
                                            self.CONNECTION_STOP)
                                    else:
                                        # We must ensure that `type` field
                                        # contains a string type object
                                        if not isinstance(
                                                handler_suffix, basestring):
                                            print 'Wrong input received: \
invalid message field `type`'

                                            self.update_status(
                                                self.CONNECTION_STOP)
                                        else:
                                            handler_name = 'handle_' + \
                                                handler_suffix
                                            if self.status == \
                                                    self.CONNECTION_INIT and \
                                                    handler_suffix != 'init':
                                                print 'Wrong input received: \
invalid message field `type`; must be "init" during the\ninitialisation phase.'

                                                self.update_status(
                                                    self.CONNECTION_STOP)
                                            else:
                                                try:
                                                    handler = getattr(
                                                        self, handler_name)
                                                except AttributeError:
                                                    print 'Wrong input \
received: invalid message field `type`'

                                                    self.update_status(
                                                        self.CONNECTION_STOP)
                                                else:
                                                    handler(data)
                                                    while self.status not in (
                                                            self.
                                                            CONNECTION_END,
                                                            self.
                                                            CONNECTION_STOP):
                                                        try:
                                                            data_size = self.\
                                                                rfile.\
                                                                read(4)
                                                        except timeout:
                                                            self.\
                                                                update_status()
                                                        else:
                                                            break
                                                    self.update_status()

            while self.status == self.CONNECTION_END:
                sleep(1)

        except ThreadExit:
            self.update_status(self.CONNECTION_STOP)
Esempio n. 15
0
 def _decode(self, raw_value: bytes) -> float:
     if len(raw_value) != self._length:
         raise ValueError(f'{self._name} floating point out of supported length')
     if raw_value[0:1] != self._exponent:
         raise ValueError(f"{self._name} floating point's exponent out of supported range")
     return s_unpack(self._format, raw_value[1:self._length])[0]
Esempio n. 16
0
def unpack(fmt, stream):
	if type(stream) == np.ndarray:
		stream0 = ''.join([chr(i) for i in stream])
	else:
		stream0 = stream
	return s_unpack(fmt, stream0)
Esempio n. 17
0
 def getHeader(self, buff):
     uid = s_unpack("I", buff[:4])[0]
     return uid
    def handle(self):
        try:
            self.update_status()

            while self.status not in (self.CONNECTION_END,
                                      self.CONNECTION_STOP):
                try:
                    data_size = self.rfile.read(4)
                except timeout:
                    self.update_status()
                    print self.status
                else:
                    break

            self.update_status()

            while self.status not in (self.CONNECTION_END,
                                      self.CONNECTION_STOP):
                if len(data_size) < 4:
                    print 'Wrong input received: EOF while waiting for \
message length (4 bytes long)'
                    self.update_status(self.CONNECTION_STOP)
                else:
                    data_size = s_unpack('!I', data_size)[0]
                    if data_size > 4096:
                        print 'Wrong input received: message size exceeds \
4096 bytes'
                        self.update_status(self.CONNECTION_STOP)
                    else:
                        try:
                            data = self.rfile.read(data_size)
                        except timeout:
                            print 'Wrong input received: timeout'
                            self.update_status(self.CONNECTION_STOP)
                        else:
                            if len(data) < data_size:
                                print 'Wrong input received: EOF while \
waiting message content (' + str(data_size) + '\nbytes long)'
                                self.update_status(self.CONNECTION_STOP)
                            else:
                                try:
                                    data = m_unpack(data, use_list=False)
                                except Exception as exception:
                                    print 'Wrong input received:', exception
                                    self.update_status(self.CONNECTION_STOP)
                                else:
                                    self.handle_test(data)
                                    try:
                                        handler_suffix = data['type']
                                    except TypeError:
                                        print "Wrong input received: invalid \
message's type"
                                        self.update_status(self.
                                                           CONNECTION_STOP)
                                    except KeyError:
                                        print 'Wrong input received: no \
`type` field in message'
                                        self.update_status(self.
                                                           CONNECTION_STOP)
                                    else:
                                        # We must ensure that `type` field
                                        # contains a string type object
                                        if not isinstance(handler_suffix,
                                                          basestring):
                                            print 'Wrong input received: \
invalid message field `type`'
                                            self.update_status(self.
                                                               CONNECTION_STOP)
                                        else:
                                            handler_name = 'handle_' + \
                                                handler_suffix
                                            if self.status == \
                                                    self.CONNECTION_INIT and \
                                                    handler_suffix != 'init':
                                                print 'Wrong input received: \
invalid message field `type`; must be "init" during the\ninitialisation phase.'
                                                self.update_status(self.
                                                    CONNECTION_STOP)
                                            else:
                                                try:
                                                    handler = getattr(self,
                                                        handler_name)
                                                except AttributeError:
                                                    print 'Wrong input \
received: invalid message field `type`'
                                                    self.update_status(
                                                        self.CONNECTION_STOP)
                                                else:
                                                    handler(data)
                                                    while self.status not in (
                                                            self.
                                                            CONNECTION_END,
                                                            self.
                                                            CONNECTION_STOP):
                                                        try:
                                                            data_size = self.\
                                                                rfile.\
                                                                read(4)
                                                        except timeout:
                                                            self.\
                                                                update_status()
                                                        else:
                                                            break
                                                    self.update_status()

            while self.status == self.CONNECTION_END:
                sleep(1)

        except ThreadExit:
            self.update_status(self.CONNECTION_STOP)