def create_block_2_response(data, request): """Generate a block 2 response for a specific request. Args: request (piccata.message.Message): A request received. Returns: piccata.message.Message: A response generated. """ data_block, more = extract_block(data, request.opt.block2.num, request.opt.block2.szx) if data_block == None: raise ValueError("Block 2 request number out of bound.") if request.mtype == CON: response = Message.AckMessage(request, code=CONTENT, payload=data_block) else: response = Message(mtype=NON, code=CONTENT, payload=data_block, token=request.token) response.opt.block2 = (request.opt.block2.num, more, request.opt.block2.szx) return response
def create_block_1_request(data, number, uri_path, mtype=CON, code=PUT, size_exp=DEFAULT_BLOCK_SIZE_EXP): """Generate a block 1 request Args: number (int): Block number to send. uri_path (tuple): A tuple containing strings representing target resource URI path. type (int): Type of the request (CON/NON). code (int): Code of the request (PUT/POST). Returns: piccata.message.Message: A request contating specific block 1 option and payload. """ data_block, more = extract_block(data, number, size_exp) if data_block == None: raise ValueError("Block 1 request number out of bound.") if type not in (CON, NON): raise ValueError("Block 1 request should be of type CON or NON") if code not in (PUT, POST): raise ValueError("Block 1 request should be PUT or POST") request = Message(mtype=mtype, code=code, payload=data_block, token=piccata.message.random_token()) request.opt.uri_path = uri_path request.opt.block1 = (number, more, size_exp) return request
def _process_empty(self, message): """Method used for processing empty messages. Args: message (piccata.message.Message): An empty message to process. """ if message.mtype is CON: logging.info( 'Empty CON message received (CoAP Ping) - replying with RST.') rst = Message.EmptyRstMessage(request) self._message_layer.send_message(rst)
def _process_request(self, request): """Method used for processing incoming requests. Args: request (piccata.message.Message): A request to process. """ if request.mtype not in (CON, NON): return if self._request_handler is not None: response = self._request_handler.receive_request(request) if response is not None: self.send_response(request, response) else: # Send reset if we do not process requests. rst = Message.EmptyRstMessage(request) self._message_layer.send_message(rst)
def _handle_trigger_request(self, request): response = None if request.mtype == piccata.constants.CON: response = Message.AckMessage( request, constants.CONTENT, _make_trigger(self.init_resource.data, self.image_resource.data, False, self.opts.reset_suppress)) else: if self.opts.mcast_dfu: address = self.REALM_LOCAL_ADDR else: address = request.remote.addr self.trigger(address, 3) return response
def receive_request(self, request): '''Request callback called by the CoAP toolkit. Note that the function signature (name, args) is expected by the CoAP toolkit.''' # TODO: remove hardcoded URIs handlers = { 'image': self._handle_image_request, 'init': self._handle_init_request, 'trig': lambda request: Message.AckMessage(request, constants.CONTENT, self .trigger_payload) } for uri, handler in handlers.items(): if request.opt.uri_path == _uri_string_to_list(self.uri_prefix + '/' + uri): response = handler(request) return response
def receive(self, data, remote, local): """Process raw messages received from transport layer. Transport layer will call this funciton on data reception. Args: data (bytes): Data received. remote (piccata.types.Endpoint): An address of the message originator. local (piccata.types.Endpoint): A destination address that data was received to. """ logging.info("Received %r from %s:%d" % (data, remote[0], remote[1])) message = Message.decode(data, remote) if self._deduplicate_message(message): return if message.mtype in (ACK, RST): req = self._remove_exchange(message.mid) if message.mtype == RST: self._transaction_layer.reset_transaction(req) return self._transaction_layer.receive_message(message, remote, local)
def create_block_2_request(number, uri_path, mtype=CON, size_exp=DEFAULT_BLOCK_SIZE_EXP): """Generate a block 2 request Args: uri_path (tuple): A tuple containing strings representing target resource URI path. number (int): Requested block number. type (int): Type of the request (CON/NON). Returns: piccata.message.Message: A request contating specific block 2 option. """ if type not in (CON, NON): raise ValueError("Block 2 request should be of type CON or NON") request = Message(mtype=mtype, code=GET, token=piccata.message.random_token()) request.opt.uri_path = uri_path request.opt.block2 = (number, False, size_exp) return request
def _handle_trigger_request(self, request): response = Message.AckMessage( request, constants.CONTENT, _make_trigger(self.init_resource.data, self.image_resource.data, self.opts.mcast_dfu, self.opts.reset_suppress)) return response
def _ack_if_confirmable(): if response.mtype is CON: ack = Message.EmptyAckMessage(response) self._message_layer.send_message(ack)
def _reset_unrecognized(): logging.info("Response not recognized - sending RST.") rst = Message.EmptyRstMessage(response) self._message_layer.send_message(rst)