Example #1
0
def register(protocol: int, rid: int, callback):
    """
    注册DCOM服务回调函数
    :param protocol: 协议号
    :param rid: 服务号
    :param callback: 回调函数.格式: func(pipe: int, src_ia: int, req: bytearray) (bytearray, int)
    :return: 返回值是应答和错误码.错误码为0表示回调成功,否则是错误码
    """
    log.info('register.protocol:%d rid:%d', protocol, rid)
    rid += protocol << 16
    _services[rid] = callback
Example #2
0
def service_callback(protocol: int, pipe: int, src_ia: int, rid: int,
                     req: bytearray) -> (bytearray, int):
    """
    回调资源号rid对应的函数
    """
    log.info('service callback.rid:%d', rid)
    rid += protocol << 16
    if rid not in _services:
        log.warn('service callback failed!can not find new rid:%d', rid)
        return None, SYSTEM_ERROR_INVALID_RID
    return _services[rid](pipe, src_ia, req)
Example #3
0
def rx_ack_frame(protocol: int, pipe: int, src_ia: int, frame: Frame):
    """
    接收到ACK帧时处理函数
    """
    _lock.acquire()

    log.info('rx ack frame.src ia:0x%x', src_ia)
    for item in _items:
        if _check_item_and_deal_ack_frame(protocol, pipe, src_ia, frame, item):
            break

    _lock.release()
Example #4
0
def send(protocol: int, pipe: int, dst_ia: int, frame: Frame):
    """
    发送数据
    """
    if frame is None:
        return

    load_param = get_load_param()
    if not load_param.is_allow_send(pipe):
        log.warn('send failed!pipe:0x%x is not allow send.token:%d', pipe, frame.control_word.token)
        return
    log.info('send frame.token:%d protocol:%d pipe:0x%x dst ia:0x%x', frame.control_word.token, protocol, pipe, dst_ia)
    load_param.send(protocol, pipe, dst_ia, frame_to_bytes(frame))
Example #5
0
def send_rst_frame(protocol: int, pipe: int, dst_ia: int, error_code: int, rid: int, token: int):
    """
    发送错误码
    """
    log.info('send rst frame:0x%x!token:%d protocol:%d pipe:0x%x dst ia:0x%x', error_code, token, protocol, pipe,
             dst_ia)
    frame = Frame()
    frame.control_word.code = CODE_RST
    frame.control_word.block_flag = 0
    frame.control_word.rid = rid
    frame.control_word.token = token
    frame.control_word.payload_len = 1
    frame.payload.append((error_code | 0x80) & 0xff)
    send(protocol, pipe, dst_ia, frame)
Example #6
0
def block_send(protocol: int, pipe: int, dst_ia: int, frame: BlockFrame):
    """
    块传输发送数据
    """
    if frame is None:
        return

    load_param = get_load_param()
    if not load_param.is_allow_send(pipe):
        log.warn('block send failed!pipe:0x%x is not allow send.token:%d', pipe, frame.control_word.token)
        return
    log.info('block send frame.token:%d protocol:%d pipe:0x%x dst ia:0x%x offset:%d', frame.control_word.token,
             protocol, pipe, dst_ia, frame.block_header.offset)
    load_param.send(protocol, pipe, dst_ia, block_frame_to_bytes(frame))
Example #7
0
def _send_frame(protocol: int, pipe: int, dst_ia: int, code: int, rid: int, token: int, data: bytearray):
    if len(data) > SINGLE_FRAME_SIZE_MAX:
        block_tx(protocol, pipe, dst_ia, code, rid, token, data)
        return

    frame = Frame()
    frame.control_word.code = code
    frame.control_word.block_flag = 0
    frame.control_word.rid = rid
    frame.control_word.token = token
    frame.control_word.payload_len = len(data)
    frame.payload.extend(data)
    log.info('send frame.token:%d', token)
    send(protocol, pipe, dst_ia, frame)
Example #8
0
def call(protocol: int, pipe: int, dst_ia: int, rid: int, timeout: int,
         req: bytearray) -> (bytearray, int):
    """
    RPC同步调用
    :param protocol: 协议号
    :param pipe: 通信管道
    :param dst_ia: 目标ia地址
    :param rid: 服务号
    :param timeout: 超时时间,单位:ms.为0表示不需要应答
    :param req: 请求数据.无数据可填bytearray()或者None
    :return: 返回值是应答字节流和错误码.错误码非SYSTEM_OK表示调用失败
    """
    log.info('call.protocol:%d pipe:0x%x dst ia:0x%x rid:%d timeout:%d',
             protocol, pipe, dst_ia, rid, timeout)
    code = CODE_CON if timeout > 0 else CODE_NON
    if not req:
        req = bytearray()

    token = get_token()
    _send_frame(protocol, pipe, dst_ia, code, rid, token, req)

    if code == CODE_NON:
        return bytearray(), SYSTEM_OK

    item = _Item()
    item.protocol = protocol
    item.pipe = pipe
    item.timeout = timeout * 1000
    item.req = req
    item.start_time = get_time()

    item.dst_ia = dst_ia
    item.rid = rid
    item.token = token
    item.code = code

    item.retry_num = 0
    item.last_retry_timestamp = get_time()

    _lock.acquire()
    _items.append(item)
    _lock.release()

    while True:
        if item.is_rx_ack:
            break

    log.info('call resp.result:%d len:%d', item.result, len(item.resp))
    return item.resp, item.result
Example #9
0
def _check_item_and_deal_ack_frame(protocol: int, pipe: int, src_ia: int, frame: Frame, item: _Item) -> bool:
    if item.protocol != protocol or item.pipe != pipe or item.dst_ia != src_ia or item.rid != frame.control_word.rid \
            or item.token != frame.control_word.token:
        return False

    log.info('deal ack frame.token:%d', item.token)
    _items.remove(item)
    if item.ack_callback:
        # 回调方式
        item.ack_callback(frame.payload, SYSTEM_OK)
    else:
        # 同步调用
        item.is_rx_ack = True
        item.result = SYSTEM_OK
        item.resp = frame.payload
    return True
Example #10
0
def call_async(protocol: int, pipe: int, dst_ia: int, rid: int, timeout: int,
               req: bytearray, ack_callback: Callable[[bytearray, int], None]):
    """
    RPC异步调用
    :param protocol: 协议号
    :param pipe: 通信管道
    :param dst_ia: 目标ia地址
    :param rid: 服务号
    :param timeout: 超时时间,单位:ms.为0表示不需要应答
    :param req: 请求数据.无数据可填bytearray()或者None
    :param ack_callback: 回调函数.原型func(resp: bytearray, error: int).参数是应答字节流和错误码.错误码非SYSTEM_OK表示调用失败
    """
    code = CODE_CON
    if timeout == 0 or not callable(ack_callback):
        code = CODE_NON
    if not req:
        req = bytearray()

    token = get_token()
    log.info(
        'call async.token:%d protocol:%d pipe:0x%x dst ia:0x%x rid:%d timeout:%d',
        token, protocol, pipe, dst_ia, rid, timeout)
    _send_frame(protocol, pipe, dst_ia, code, rid, token, req)

    if code == CODE_NON:
        return

    item = _Item()
    item.ack_callback = ack_callback
    item.protocol = protocol
    item.pipe = pipe
    item.timeout = timeout * 1000
    item.req = req
    item.start_time = get_time()

    item.dst_ia = dst_ia
    item.rid = rid
    item.token = token
    item.code = code

    item.retry_num = 0
    item.last_retry_timestamp = get_time()

    _lock.acquire()
    _items.append(item)
    _lock.release()