def processRegisterResponse(encodedControlResponse): """ This is called when the register route command responds to decode the encodedControlResponse as a TLV ControlParametersResponse message containing one ControlParameters. On success, print the ControlParameters values which should be the same as requested. :param Blob encodedControlResponse: The TLV-encoded ControlParametersResponse. """ decodedControlResponse = \ control_parameters_pb2.ControlParametersTypes.ControlParametersResponseMessage() ProtobufTlv.decode(decodedControlResponse, encodedControlResponse) controlResponse = decodedControlResponse.control_response lowestErrorCode = 400 if controlResponse.status_code >= lowestErrorCode: dump( "Face create command got error, code " + str(controlResponse.status_code) + ": " + controlResponse.status_text) return if len(controlResponse.control_parameters) != 1: dump( "Face create command response does not have one ControlParameters") return # Success. Print the ControlParameters response. controlParameters = controlResponse.control_parameters[0] dump( "Successful in name registration: ControlParameters(Name: " + ProtobufTlv.toName(controlParameters.name.component).toUri() + ", FaceId: " + str(controlParameters.face_id) + ", Origin: " + str(controlParameters.origin) + ", Cost: " + str(controlParameters.cost) + ", Flags: " + str(controlParameters.flags) + ")")
def printRibEntries(encodedMessage): """ This is called when all the segments are received to decode the encodedMessage as repeated TLV RibEntry messages and display the values. :param Blob encodedMessage: The repeated TLV-encoded RibEntry. """ ribEntryMessage = rib_entry_pb2.RibEntryMessage() ProtobufTlv.decode(ribEntryMessage, encodedMessage) dump("RIB:"); for ribEntry in ribEntryMessage.rib_entry: line = "" for component in ribEntry.name.component: # component may be a bytes type, so use Blob to convert to str. line += "/" + Blob(component, False).toRawStr() # Show the routes. for route in ribEntry.routes: line += (" route={faceId=" + str(route.face_id) + " (origin=" + str(route.origin) + " cost=" + str(route.cost)) if (route.flags & 1) != 0: line += " ChildInherit" if (route.flags & 2) != 0: line += " Capture" if route.HasField("expiration_period"): line += " expirationPeriod=" + str(route.expiration_period) line += ")}" dump(line)
def main(): # Construct a sample FibEntry message using the structure in fib_entry_pb2 # which was produced by protoc. message = fib_entry_pb2.FibEntryMessage() message.fib_entry.name.component.append("ndn") message.fib_entry.name.component.append("ucla") nextHopRecord = message.fib_entry.next_hop_records.add() nextHopRecord.face_id = 16 nextHopRecord.cost = 1 # Encode the Protobuf message object as TLV. encoding = ProtobufTlv.encode(message) decodedMessage = fib_entry_pb2.FibEntryMessage() ProtobufTlv.decode(decodedMessage, encoding) dump("Re-decoded FibEntry:") # This should print the same values that we put in message above. value = "" for component in decodedMessage.fib_entry.name.component: value += "/" + component value += " nexthops = {" for next_hop_record in decodedMessage.fib_entry.next_hop_records: value += ("faceid=" + repr(next_hop_record.face_id) + " (cost=" + repr(next_hop_record.cost) + ")") value += " }" dump(value)
def onVerifiedAppRequest(interest): # TODO: for now, we automatically grant access to any valid signed interest print("verified! send response!") message = AppRequestMessage() ProtobufTlv.decode( message, interest.getName().get(prefix.size() + 1).getValue()) certName = Name("/".join(message.command.idName.components)) dataPrefix = Name("/".join( message.command.dataPrefix.components)) appName = message.command.appName isUpdated = self.updateTrustSchema(appName, certName, dataPrefix, True) response = Data(interest.getName()) if isUpdated: response.setContent( "{\"status\": 200, \"message\": \"granted, trust schema updated OK\" }" ) self.log.info( "Verified and granted application publish request") else: response.setContent( "{\"status\": 400, \"message\": \"not granted, requested publishing namespace already exists\" }" ) self.log.info( "Verified and but requested namespace already exists") self.sendData(response) return
def general_status(): def convert_time(timestamp): ret = datetime.fromtimestamp(float(timestamp) / 1000.0) return str(ret) interest = Interest("/localhost/nfd/status/general") interest.mustBeFresh = True interest.canBePrefix = True ret = run_until_complete(fetch_data_packet(server.face, interest)) if isinstance(ret, Data): name = ret.name.toUri() msg = GeneralStatus() try: ProtobufTlv.decode(msg, ret.content) except RuntimeError as exc: logging.fatal("Decoding Error %s", exc) return "Decoding Error" status = decode_dict(msg) status['start_timestamp'] = convert_time(status['start_timestamp']) status['current_timestamp'] = convert_time( status['current_timestamp']) return render_template('general-status.html', refer_name='/general-status', name=name, status=status) else: logging.info("No response: general status") return redirect('/')
def processCreateFaceResponse(encodedControlResponse, prefix, face, enabled): """ This is called when the face create command responds to decode the encodedControlResonse as a TLV ControlResponse message containing one ControlParameters. Get the face ID and call registerRoute(). :param Blob encodedControlResponse: The TLV-encoded ControlResponse. """ decodedControlResponse = \ control_parameters_pb2.ControlParametersTypes.ControlParametersResponseMessage() ProtobufTlv.decode(decodedControlResponse, encodedControlResponse) controlResponse = decodedControlResponse.control_response lowestErrorCode = 400 if controlResponse.status_code >= lowestErrorCode: dump("Face create command got error, code " + str(controlResponse.status_code) + ": " + controlResponse.status_text) enabled[0] = False return if len(controlResponse.control_parameters) != 1: dump( "Face create command response does not have one ControlParameters") enabled[0] = False return faceId = controlResponse.control_parameters[0].face_id dump("Created face ID " + str(faceId)) registerRoute(prefix, faceId, face, enabled)
def main(): # Construct a sample FibEntry message using the structure in fib_entry_pb2 # which was produced by protoc. message = fib_entry_pb2.FibEntryMessage() message.fib_entry.name.component.append(b"ndn") message.fib_entry.name.component.append(b"ucla") nextHopRecord = message.fib_entry.next_hop_records.add() nextHopRecord.face_id = 16 nextHopRecord.cost = 1 # Encode the Protobuf message object as TLV. encoding = ProtobufTlv.encode(message) decodedMessage = fib_entry_pb2.FibEntryMessage() ProtobufTlv.decode(decodedMessage, encoding) dump("Re-decoded FibEntry:") # This should print the same values that we put in message above. value = "" value += ProtobufTlv.toName( decodedMessage.fib_entry.name.component).toUri() value += " nexthops = {" for next_hop_record in decodedMessage.fib_entry.next_hop_records: value += ("faceid=" + repr(next_hop_record.face_id) + " (cost=" + repr(next_hop_record.cost) + ")") value += " }" dump(value)
def processCreateFaceResponse(encodedControlResponse, prefix, face, enabled): """ This is called when the face create command responds to decode the encodedControlResonse as a TLV ControlResponse message containing one ControlParameters. Get the face ID and call registerRoute(). :param Blob encodedControlResponse: The TLV-encoded ControlResponse. """ decodedControlResponse = \ control_parameters_pb2.ControlParametersTypes.ControlParametersResponseMessage() ProtobufTlv.decode(decodedControlResponse, encodedControlResponse) controlResponse = decodedControlResponse.control_response lowestErrorCode = 400 if controlResponse.status_code >= lowestErrorCode: dump( "Face create command got error, code " + str(controlResponse.status_code) + ": " + controlResponse.status_text) enabled[0] = False return if len(controlResponse.control_parameters) != 1: dump( "Face create command response does not have one ControlParameters") enabled[0] = False return faceId = controlResponse.control_parameters[0].face_id dump("Created face ID " + str(faceId)) registerRoute(prefix, faceId, face, enabled)
def printFaceStatuses(self, encodedMessage): """ This is called when all the segments are received to decode the encodedMessage repeated TLV FaceStatus messages and display the values. :param Blob encodedMessage: The repeated TLV-encoded FaceStatus. """ faceStatusMessage = face_status_pb2.FaceStatusMessage() ProtobufTlv.decode(faceStatusMessage, encodedMessage) self.dump("Faces:") for faceStatus in faceStatusMessage.face_status: '''ignore those on-demand faces created by APPs, especially this node.py APP''' if (faceStatus.local_uri == 'tcp4://127.0.0.1:6363' and \ faceStatus.face_scope == 1 and \ faceStatus.face_persistency == 1 and \ faceStatus.link_type != 1): continue line = "" # Format to look the same as "nfd-status -f". line += (" faceid=" + str(faceStatus.face_id) + " remote=" + faceStatus.uri + " local=" + faceStatus.local_uri) line += (" " + ("local" if faceStatus.face_scope == 1 else "non-local") + " " + ("permanent" if faceStatus.face_persistency == 2 else ("on-demand" if faceStatus.face_persistency == 1 else "persistent")) + " " + ("multi-access" if faceStatus.link_type == 1 else "point-to-point")) self.dump(line)
def route_list(): def decode_route_list(msg): ret = [] for item in msg: name = decode_name(item.name) routes = decode_list(item.route) ret.append((name, routes)) return ret interest = Interest("/localhost/nfd/rib/list") interest.mustBeFresh = True interest.canBePrefix = True ret = run_until_complete(fetch_data_packet(server.face, interest)) if isinstance(ret, Data): name = ret.name.toUri() msg = RibStatusMessage() try: ProtobufTlv.decode(msg, ret.content) except RuntimeError as exc: logging.fatal("Decoding Error %s", exc) return "Decoding Error" rib_list = decode_route_list(msg.rib_entry) return render_template('route-list.html', refer_name='/route-list', rib_list=rib_list, **request.args.to_dict()) else: logging.info("No response: route-list") return redirect('/')
def face_list(): interest = Interest("/localhost/nfd/faces/list") interest.mustBeFresh = True interest.canBePrefix = True ret = run_until_complete(fetch_data_packet(server.face, interest)) if isinstance(ret, Data): name = ret.name.toUri() msg = FaceStatusMessage() try: ProtobufTlv.decode(msg, ret.content) except RuntimeError as exc: logging.fatal("Decoding Error %s", exc) return "Decoding Error" face_list = decode_list(msg.face_status) fields = list(face_list[0].keys()) fields_collapse = [ field for field in set(fields) - {'face_id', 'uri'} ] return render_template('face-list.html', refer_name='/face-list', face_list=face_list, fields_collapse=fields_collapse, **request.args.to_dict()) else: logging.info("No response: face-list") return redirect('/')
def printFaceStatuses(encodedMessage): """ This is called when all the segments are received to decode the encodedMessage repeated TLV FaceStatus messages and display the values. :param Blob encodedMessage: The repeated TLV-encoded FaceStatus. """ faceStatusMessage = face_status_pb2.FaceStatusMessage() ProtobufTlv.decode(faceStatusMessage, encodedMessage) dump("Faces:"); for faceStatus in faceStatusMessage.face_status: line = "" # Format to look the same as "nfd-status -f". line += (" faceid=" + str(faceStatus.face_id) + " remote=" + faceStatus.uri + " local=" + faceStatus.local_uri) if faceStatus.HasField("expiration_period"): # Convert milliseconds to seconds. line += (" expires=" + str(round(faceStatus.expiration_period / 1000.0)) + "s") line += (" counters={" + "in={" + str(faceStatus.n_in_interests) + "i " + str(faceStatus.n_in_datas) + "d " + str(faceStatus.n_in_bytes) + "B}" + " out={" + str(faceStatus.n_out_interests) + "i "+ str(faceStatus.n_out_datas) + "d " + str(faceStatus.n_out_bytes) + "B}" + "}" + " " + ("local" if faceStatus.face_scope == 1 else "non-local") + " " + ("permanent" if faceStatus.face_persistency == 2 else ("on-demand" if faceStatus.face_persistency == 1 else "persistent")) + " " + ("multi-access" if faceStatus.link_type == 1 else "point-to-point")) dump(line)
def strategy_list(): def decode_strategy(msg): return [{ "name": decode_name(item.name), "strategy": decode_name(item.strategy.name), } for item in msg] interest = Interest("/localhost/nfd/strategy-choice/list") interest.mustBeFresh = True interest.canBePrefix = True ret = run_until_complete(fetch_data_packet(server.face, interest)) if isinstance(ret, Data): msg = StrategyChoiceMessage() try: ProtobufTlv.decode(msg, ret.content) except RuntimeError as exc: logging.info("Decoding Error %s", exc) return "Decoding Error" strategy_list = decode_strategy(msg.strategy_choice) return render_template('strategy-list.html', refer_name='/strategy-list', strategy_list=strategy_list, **request.args.to_dict()) else: logging.info("No response: strategy-list") return redirect('/')
def onLightingCommand(self, prefix, interest, transport, prefixId): interestName = Name(interest.getName()) #d = Data(interest.getName().getPrefix(prefix.size()+1)) d = Data(interest.getName()) # get the command parameters from the name try: commandComponent = interest.getName().get(prefix.size()) commandParams = interest.getName().get(prefix.size()+1) lightingCommand = LightCommandMessage() ProtobufTlv.decode(lightingCommand, commandParams.getValue()) self.log.info("Command: " + commandComponent.toEscapedString()) requestedColor = lightingCommand.command.pattern.colors[0] colorStr = str((requestedColor.r, requestedColor.g, requestedColor.b)) self.log.info("Requested color: " + colorStr) self.setPayloadColor(0, requestedColor) self.sendLightPayload(1) d.setContent("Gotcha: " + colorStr+ "\n") except Exception as e: print e d.setContent("Bad command\n") finally: d.getMetaInfo().setFinalBlockID(0) self.signData(d) encodedData = d.wireEncode() transport.send(encodedData.toBuffer())
def processRegisterResponse(encodedControlResponse): """ This is called when the register route command responds to decode the encodedControlResponse as a TLV ControlParametersResponse message containing one ControlParameters. On success, print the ControlParameters values which should be the same as requested. :param Blob encodedControlResponse: The TLV-encoded ControlParametersResponse. """ decodedControlResponse = \ control_parameters_pb2.ControlParametersTypes.ControlParametersResponseMessage() ProtobufTlv.decode(decodedControlResponse, encodedControlResponse) controlResponse = decodedControlResponse.control_response lowestErrorCode = 400 if controlResponse.status_code >= lowestErrorCode: dump("Face create command got error, code " + str(controlResponse.status_code) + ": " + controlResponse.status_text) return if len(controlResponse.control_parameters) != 1: dump( "Face create command response does not have one ControlParameters") return # Success. Print the ControlParameters response. controlParameters = controlResponse.control_parameters[0] dump("Successful in name registration: ControlParameters(Name: " + ProtobufTlv.toName(controlParameters.name.component).toUri() + ", FaceId: " + str(controlParameters.face_id) + ", Origin: " + str(controlParameters.origin) + ", Cost: " + str(controlParameters.cost) + ", Flags: " + str(controlParameters.flags) + ")")
def _onConfigurationReceived(self, prefix, interest, transport, prefixId): # the interest we get here is signed by HMAC, let's verify it self.tempPrefixId = prefixId # didn't get it from register because of the event loop interestName = interest.getName() replyData = Data(interestName) if len(interestName) == len(prefix): # this is a discovery request. Check the exclude to see if we should # return our serial serial = self.getSerial() serialComponent = Name.Component(serial) if not interest.getExclude().matches(serialComponent): replyData.setContent(serial) self.sendData(replyData, transport, False) # no point in signing elif (self._hmacHandler.verifyInterest(interest)): # we have a match! decode the network parameters configComponent = interest.getName()[len(prefix)+1] replyData.setContent('200') self._hmacHandler.signData(replyData, keyName=self.prefix) transport.send(replyData.wireEncode().buf()) environmentConfig = DeviceConfigurationMessage() ProtobufTlv.decode(environmentConfig, configComponent.getValue()) networkPrefix = self._extractNameFromField(environmentConfig.configuration.networkPrefix) controllerName = self._extractNameFromField(environmentConfig.configuration.controllerName) controllerName = Name(networkPrefix).append(controllerName) self._policyManager.setEnvironmentPrefix(networkPrefix) self._policyManager.setTrustRootIdentity(controllerName) self.deviceSuffix = self._extractNameFromField(environmentConfig.configuration.deviceSuffix) self._configureIdentity = Name(networkPrefix).append(self.deviceSuffix) self._sendCertificateRequest(self._configureIdentity)
def _onConfigurationReceived(self, prefix, interest, face, interestFilterId, filter): # the interest we get here is signed by HMAC, let's verify it self.tempPrefixId = interestFilterId # didn't get it from register because of the event loop dataName = Name(interest.getName()) replyData = Data(dataName) if (self._hmacHandler.verifyInterest(interest)): # we have a match! decode the controller's name configComponent = interest.getName().get(prefix.size()) replyData.setContent('200') self._hmacHandler.signData(replyData, keyName=self.prefix) self.face.putData(replyData) environmentConfig = DeviceConfigurationMessage() ProtobufTlv.decode(environmentConfig, configComponent.getValue()) networkPrefix = self._extractNameFromField( environmentConfig.configuration.networkPrefix) controllerName = self._extractNameFromField( environmentConfig.configuration.controllerName) controllerName = Name(networkPrefix).append(controllerName) self._policyManager.setEnvironmentPrefix(networkPrefix) self._policyManager.setTrustRootIdentity(controllerName) self.deviceSuffix = self._extractNameFromField( environmentConfig.configuration.deviceSuffix) self._configureIdentity = Name(networkPrefix).append( self.deviceSuffix) self._sendCertificateRequest(self._configureIdentity)
def printRibEntries(encodedMessage): """ This is called when all the segments are received to decode the encodedMessage as repeated TLV RibEntry messages and display the values. :param Blob encodedMessage: The repeated TLV-encoded RibEntry. """ ribEntryMessage = rib_entry_pb2.RibEntryMessage() ProtobufTlv.decode(ribEntryMessage, encodedMessage) dump("RIB:"); for ribEntry in ribEntryMessage.rib_entry: line = "" line += ProtobufTlv.toName(ribEntry.name.component).toUri() # Show the routes. for route in ribEntry.routes: line += (" route={faceId=" + str(route.face_id) + " (origin=" + str(route.origin) + " cost=" + str(route.cost)) if (route.flags & 1) != 0: line += " ChildInherit" if (route.flags & 2) != 0: line += " Capture" if route.HasField("expiration_period"): line += " expirationPeriod=" + str(route.expiration_period) line += ")}" dump(line)
def _onConfigurationReceived(self, prefix, interest, transport, prefixId): # the interest we get here is signed by HMAC, let's verify it self.tempPrefixId = prefixId # didn't get it from register because of the event loop dataName = Name(interest.getName()) replyData = Data(dataName) if (self._hmacHandler.verifyInterest(interest)): # we have a match! decode the controller's name configComponent = interest.getName().get(prefix.size()) replyData.setContent('200') self._hmacHandler.signData(replyData, keyName=self.prefix) transport.send(replyData.wireEncode().buf()) environmentConfig = DeviceConfigurationMessage() ProtobufTlv.decode(environmentConfig, configComponent.getValue()) networkPrefix = self._extractNameFromField(environmentConfig.configuration.networkPrefix) controllerName = self._extractNameFromField(environmentConfig.configuration.controllerName) controllerName = Name(networkPrefix).append(controllerName) self._policyManager.setEnvironmentPrefix(networkPrefix) self._policyManager.setTrustRootIdentity(controllerName) self.deviceSuffix = self._extractNameFromField(environmentConfig.configuration.deviceSuffix) self._configureIdentity = Name(networkPrefix).append(self.deviceSuffix) self._sendCertificateRequest(self._configureIdentity)
async def send_cmd_interest(self): event_loop = asyncio.get_event_loop() face_task = event_loop.create_task(self.face_loop()) parameter = RepoCommandParameterMessage() for compo in self.prefix: parameter.repo_command_parameter.name.component.append(compo.getValue().toBytes()) parameter.repo_command_parameter.start_block_id = self.latest_tp parameter.repo_command_parameter.end_block_id = parameter.repo_command_parameter.start_block_id param_blob = ProtobufTlv.encode(parameter) # Prepare cmd interest name = Name(self.repo_name).append("insert").append(Name.Component(param_blob)) interest = Interest(name) interest.canBePrefix = True self.face.makeCommandInterest(interest) logging.info("Express interest: {}".format(interest.getName())) ret = await fetch_data_packet(self.face, interest) if not isinstance(ret, Data): logging.warning("Insertion failed") else: # Parse response response = RepoCommandResponseMessage() try: ProtobufTlv.decode(response, ret.content) logging.info('Insertion command accepted: status code {}' .format(response.repo_command_response.status_code)) except RuntimeError as exc: logging.warning('Response decoding failed', exc)
def versionFromCommandMessage(self, component): command = RepoCommandParameterMessage() try: ProtobufTlv.decode(command, component.getValue()) except Exception as e: logger.warn(e) # last component of name to insert is version versionStr = command.repo_command_parameter.name.component[-1] return versionStr
def onCecCommand(self, interest): self.log.debug("Received CEC command") # check command interest name # verify command interest message = pb.CommandMessage() ProtobufTlv.decode(message, interest.getName().get(3).getValue()) self.loop.call_soon(self.processCommands, message) data = Data(interest.getName()) data.setContent('ACK') return data
def onCommandData(interest, data): global current_insertion # global current_status now = time.time() # assume it's a command response response = RepoCommandResponseMessage() ProtobufTlv.decode(response, data.getContent()) current_status = response.repo_command_response.status_code current_insertion = response.repo_command_response.process_id logger.debug("Response status code: " + str(current_status) + ", process id: " + str(current_insertion) + ", insert #" + str(response.repo_command_response.insert_num))
def decode_cmd_response_blob(data: Data) -> RepoCommandResponseMessage: """ Decode the command response and return a RepoCommandResponseMessage object. Throw RuntimeError on decoding failure. """ response = RepoCommandResponseMessage() response_blob = data.getContent() try: ProtobufTlv.decode(response, response_blob) except RuntimeError as exc: raise exc return response
async def run(self, repo_name: str, prefix: str, start_block_id: int, end_block_id: int): """ Send a delete command to remove all the data within [start_block_id, end_block_id]. """ # Send command interest prefix = Name(prefix) parameter = RepoCommandParameterMessage() for compo in prefix: parameter.repo_command_parameter.name.component.append( compo.getValue().toBytes()) parameter.repo_command_parameter.start_block_id = start_block_id parameter.repo_command_parameter.end_block_id = end_block_id param_blob = ProtobufTlv.encode(parameter) name = Name(repo_name).append('delete').append( Name.Component(param_blob)) interest = Interest(name) self.face.makeCommandInterest(interest) logging.info('Send delete command interest') ret = await fetch_data_packet(self.face, interest) # Parse response if not isinstance(ret, Data): logging.warning('Delete error') return response = RepoCommandResponseMessage() try: ProtobufTlv.decode(response, ret.content) except RuntimeError as exc: logging.warning('Response decoding failed', exc) process_id = response.repo_command_response.process_id status_code = response.repo_command_response.status_code logging.info('Delete process {} accepted, status {}'.format( process_id, status_code)) # Use delete check command to probe if delete process is completed checker = CommandChecker(self.face, self.keychain) while True: response = await checker.check_delete(repo_name, process_id) if response.repo_command_response.status_code == 300: await asyncio.sleep(1) elif response.repo_command_response.status_code == 200: logging.info( 'Delete process {} status: {}, delete_num: {}'.format( process_id, response.repo_command_response.status_code, response.repo_command_response.delete_num)) break else: # Shouldn't get here assert (False)
async def insert_segmented_file(self): event_loop = asyncio.get_event_loop() face_task = event_loop.create_task(self.face_loop()) parameter = RepoCommandParameterMessage() for compo in self.name_at_repo: parameter.repo_command_parameter.name.component.append( compo.getValue().toBytes()) parameter.repo_command_parameter.start_block_id = 0 parameter.repo_command_parameter.end_block_id = self.n_packets - 1 param_blob = ProtobufTlv.encode(parameter) # Prepare cmd interest name = Name(self.repo_name).append('insert').append( Name.Component(param_blob)) interest = Interest(name) self.face.makeCommandInterest(interest) logging.info('Send insert command interest') ret = await fetch_data_packet(self.face, interest) if not isinstance(ret, Data): logging.warning('Insert failed') return response = RepoCommandResponseMessage() try: ProtobufTlv.decode(response, ret.content) except RuntimeError as exc: logging.warning('Response decoding failed', exc) process_id = response.repo_command_response.process_id status_code = response.repo_command_response.status_code logging.info('Insertion process {} accepted: status code {}'.format( process_id, status_code)) # Use insert check command to probe if insert process is completed checker = CommandChecker(self.face, self.keychain) while True: response = await checker.check_insert(self.repo_name, process_id) if response is None or response.repo_command_response.status_code == 300: await asyncio.sleep(1) elif response.repo_command_response.status_code == 200: logging.info( 'Insert process {} status: {}, insert_num: {}'.format( process_id, response.repo_command_response.status_code, response.repo_command_response.insert_num)) break else: # Shouldn't get here assert (False) self.running = False await face_task
def onRepoCommandResponse(interest, data): # repo_command_response_pb2 was produced by protoc. response = repo_command_response_pb2.RepoCommandResponseMessage() try: ProtobufTlv.decode(response, data.content) except: print("Cannot decode the repo command response") if response.repo_command_response.status_code == 100: if __debug__: print("Insertion started") else: print("Got repo command error code", response.repo_command_response.status_code)
async def issue_command_interest(self, interest): ret = await fetch_data_packet(self.face, interest) if isinstance(ret, Data): response = ControlResponseMessage() try: ProtobufTlv.decode(response, ret.content) dic = self.response_to_dict(response.control_response) logging.info("Issue command Interest with %s", dic) return dic except RuntimeError as exc: logging.fatal('Decode failed %s', exc) return None
def printChannelStatuses(self, encodedMessage): """ This is called when all the segments are received to decode the encodedMessage repeated TLV ChannelStatus messages and display the values. :param Blob encodedMessage: The repeated TLV-encoded ChannelStatus. """ channelStatusMessage = channel_status_pb2.ChannelStatusMessage() ProtobufTlv.decode(channelStatusMessage, encodedMessage) self.dump("Channels:") for channelStatus in channelStatusMessage.channel_status: # Format to look the same as "nfd-status -c". self.dump(" " + channelStatus.local_uri)
def printChannelStatuses(encodedMessage): """ This is called when all the segments are received to decode the encodedMessage repeated TLV ChannelStatus messages and display the values. :param Blob encodedMessage: The repeated TLV-encoded ChannelStatus. """ channelStatusMessage = channel_status_pb2.ChannelStatusMessage() ProtobufTlv.decode(channelStatusMessage, encodedMessage) dump("Channels:"); for channelStatus in channelStatusMessage.channel_status: # Format to look the same as "nfd-status -c". dump(" " + channelStatus.local_uri)
async def face_event(self): last_seq = -1 retry_time = 3000 retry_count_limit = 60000 // retry_time retry_count = 0 while self.running and self.face: name = Name("/localhost/nfd/faces/events") face_interest = Interest() if last_seq >= 0: name.appendSequenceNumber(last_seq + 1) face_interest.canBePrefix = False else: face_interest.mustBeFresh = True face_interest.canBePrefix = True logging.info("Face event notification stream %s", name.toUri()) face_interest.name = name # face_interest.interestLifetimeMilliseconds = 60000 face_interest.interestLifetimeMilliseconds = retry_time ret = await fetch_data_packet(self.face, face_interest) timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") if isinstance(ret, Data): retry_count = 0 last_seq = ret.name[-1].toSequenceNumber() face_event = FaceEventNotificationMessage() try: ProtobufTlv.decode(face_event, ret.content) dic = self.face_event_to_dict(face_event.face_event_notification) dic['seq'] = str(last_seq) dic['time'] = timestamp self.emit('face event', dic) self.event_list.append(dic) except RuntimeError as exc: logging.fatal('Decode failed %s', exc) last_seq = -1 elif ret is None: if retry_count >= retry_count_limit: logging.info("No response: face event") last_seq = -1 retry_count = 0 else: retry_count += 1 else: logging.info("NFD is not running: start reconnection") self.start_reconnection() return await asyncio.sleep(0.1)
def onData(interest, data): # repo_command_response_pb2 was produced by protoc. response = repo_command_response_pb2.RepoCommandResponseMessage() try: ProtobufTlv.decode(response, data.content) except: dump("Cannot decode the repo command response") onFailed() if response.repo_command_response.status_code == 100: onInsertStarted() else: dump("Got repo command error code", response.repo_command_response.status_code) onFailed()
def _beginPairing(self, encryptedMessage): # base64 decode, decrypt, protobuf decode responseCode = 202 try: encryptedBytes = base64.urlsafe_b64decode(str(encryptedMessage.getValue())) decryptedBytes = self._identityManager.decryptAsIdentity(encryptedBytes, self.prefix) message = DevicePairingInfoMessage() ProtobufTlv.decode(message, decryptedBytes) except: responseCode = 500 else: info = message.info self.loop.call_soon(self._addDeviceToNetwork, info.deviceSerial, info.deviceSuffix, info.devicePin) return responseCode
def decode_cmd_param_blob( interest: Interest) -> RepoCommandParameterMessage: """ Decode the command interest and return a RepoCommandParameterMessage object. Command interests have the format of: /<routable_repo_prefix>/insert/<cmd_param_blob>/<timestamp>/<random-value>/<SignatureInfo>/<SignatureValue> Throw RuntimeError on decoding failure. """ parameter = RepoCommandParameterMessage() param_blob = interest.getName()[-5].getValue() try: ProtobufTlv.decode(parameter, param_blob) except RuntimeError as exc: raise exc return parameter
def wireDecode(self, input): """ Decode the input and update this ContentMetaInfo. :param input: The array with the bytes to decode. :type input: An array type with int elements """ meta = ContentMetaInfoMessage() ProtobufTlv.decode(meta, input) self.clear() self._contentType = meta.content_meta_info.content_type self._timestamp = float(meta.content_meta_info.timestamp) self._hasSegments = meta.content_meta_info.has_segments if len(meta.content_meta_info.other) > 0: self._other = Blob(bytearray(meta.content_meta_info.other), False)
def onLightingCommand(self, prefix, interest, transport, prefixId): #print datetime.datetime.now() self.receiveFile.write('{0:f}'.format(self.unix_time_now()) + '\n') interestName = Name(interest.getName()) #interstname: /ndn/ucla.edu/sculptures/ai_bus/lights/setRGB/%83%0D%84%0B%87%09%89%01%04%8A%01%01%8B%01%01 #d: <pyndn.data.Data object at 0xb64825d0> print "interstname", interestName.toUri() d = Data(interest.getName()) # get the command parameters from the name try: commandComponent = interest.getName().get(prefix.size()) #print commandComponent.toEscapedString():setRGB #print "prefix ",prefix.toUri():/ndn/ucla.edu/sculpture/ai_bus/lights #print "get name",interest.getName().toUri() commandParams = interest.getName().get(prefix.size()+1) #print "commandParams ",commandParams:%83%0D%84%0B%87%09%89%01%04%8A%01%01%8B%01%01 lightingCommand = LightCommandMessage() ProtobufTlv.decode(lightingCommand, commandParams.getValue()) #self.log.info("Command: " + commandComponent.toEscapedString()) requestedColor = lightingCommand.command.pattern.colors[0] colorStr = str((requestedColor.r, requestedColor.g, requestedColor.b)) #self.log.info("Requested color: " + colorStr) self.setPayloadColor(0, requestedColor) self.lightState = not self.lightState if self.lightState: print "Off" else: print "On" #print requestedColor self.sendLightPayload(1) d.setContent("Gotcha: " + colorStr+ "\n") except KeyboardInterrupt: print "key interrupt" sys.exit(1) except Exception as e: print e d.setContent("Bad command\n") finally: d.getMetaInfo().setFinalBlockID(0) self.signData(d) encodedData = d.wireEncode() transport.send(encodedData.toBuffer())
def processFaceStatus(encodedFaceStatus, prefix, uri, face, enabled): """ This is called when all the segments are received to decode the encodedFaceStatus as a TLV FaceStatus message. If the face ID exists for the face URL, use it to call registerRoute(), otherwise send a /localhost/nfd/faces/create command to create the face. :param Blob encodedFaceStatus: The TLV-encoded FaceStatus. :param Name prefix: The prefix name to register. :param str uri: The remote URI in case we need to tell NFD to create a face. :param Face face: The Face which is used to sign the command interest and call expressInterest. :param enabled: On success or error, set enabled[0] = False. :type enabled: An array with one bool element """ if encodedFaceStatus.size() == 0: # No result, so we need to tell NFD to create the face. # Encode the ControlParameters. message = \ control_parameters_pb2.ControlParametersTypes.ControlParametersMessage() message.control_parameters.uri = uri encodedControlParameters = ProtobufTlv.encode(message) interest = Interest(Name("/localhost/nfd/faces/create")) interest.getName().append(encodedControlParameters) interest.setInterestLifetimeMilliseconds(10000) def onData(localInterest, data): processCreateFaceResponse(data.getContent(), prefix, face, enabled) def onTimeout(localInterest): enabled[0] = False dump("Face create command timed out.") # Sign and express the interest. face.makeCommandInterest(interest) face.expressInterest(interest, onData, onTimeout) else: decodedFaceStatus = face_status_pb2.FaceStatusMessage() ProtobufTlv.decode(decodedFaceStatus, encodedFaceStatus) faceId = decodedFaceStatus.face_status[0].face_id dump("Found face ID ", faceId) registerRoute(prefix, faceId, face, enabled)
def _updateDeviceCapabilities(self, interest): """ Take the received capabilities update interest and update our directory listings. """ # we assume the sender is the one who signed the interest... signature = self._policyManager._extractSignature(interest) certificateName = signature.getKeyLocator().getKeyName() senderIdentity = IdentityCertificate.certificateNameToPublicKeyName( certificateName).getPrefix(-1) self.log.info('Updating capabilities for {}'.format( senderIdentity.toUri())) # get the params from the interest name messageComponent = interest.getName().get(self.prefix.size() + 1) message = UpdateCapabilitiesCommandMessage() ProtobufTlv.decode(message, messageComponent.getValue()) # we remove all the old capabilities for the sender tempDirectory = defaultdict(list) for keyword in self._directory: tempDirectory[keyword] = [ cap for cap in self._directory[keyword] if not senderIdentity.match(Name(cap['name'])) ] # then we add the ones from the message for capability in message.capabilities: capabilityPrefix = Name() for component in capability.commandPrefix.components: capabilityPrefix.append(component) commandUri = capabilityPrefix.toUri() if not senderIdentity.match(capabilityPrefix): self.log.error( "Node {} tried to register another prefix: {} - ignoring update" .format(senderIdentity.toUri(), commandUri)) else: for keyword in capability.keywords: allUris = [info['name'] for info in tempDirectory[keyword]] if capabilityPrefix not in allUris: listing = { 'signed': capability.needsSignature, 'name': commandUri } tempDirectory[keyword].append(listing) self._directory = tempDirectory
def _handleCertificateRequest(self, interest): """ Extracts a public key name and key bits from a command interest name component. Generates a certificate if the request is verifiable. This expects an HMAC signed interest. """ message = CertificateRequestMessage() commandParamsTlv = interest.getName().get(self.prefix.size() + 1) ProtobufTlv.decode(message, commandParamsTlv.getValue()) signature = HmacHelper.extractInterestSignature(interest) deviceSerial = str( signature.getKeyLocator().getKeyName().get(-1).getValue()) response = Data(interest.getName()) certData = None hmac = None try: hmac = self._hmacDevices[deviceSerial] if hmac.verifyInterest(interest): certData = self._createCertificateFromRequest(message) # remove this hmac; another request will require a new pin self._hmacDevices.pop(deviceSerial) except KeyError: self.log.warn( 'Received certificate request for device with no registered key' ) except SecurityException as e: self.log.warn('Could not create device certificate: ' + str(e)) else: self.log.info( 'Creating certificate for device {}'.format(deviceSerial)) if certData is not None: response.setContent(certData.wireEncode()) response.getMetaInfo().setFreshnessPeriod( 10000) # should be good even longer else: response.setContent("Denied") if hmac is not None: hmac.signData(response) self.sendData(response, False)
def onVerifiedAppRequest(interest): # TODO: for now, we automatically grant access to any valid signed interest print("verified! send response!") message = AppRequestMessage() ProtobufTlv.decode(message, interest.getName().get(prefix.size() + 1).getValue()) certName = Name("/".join(message.command.idName.components)) dataPrefix = Name("/".join(message.command.dataPrefix.components)) appName = message.command.appName isUpdated = self.updateTrustSchema(appName, certName, dataPrefix, True) response = Data(interest.getName()) if isUpdated: response.setContent("{\"status\": 200, \"message\": \"granted, trust schema updated OK\" }") self.log.info("Verified and granted application publish request") else: response.setContent("{\"status\": 400, \"message\": \"not granted, requested publishing namespace already exists\" }") self.log.info("Verified and but requested namespace already exists") self.sendData(response) return
def on_command(self, _prefix, interest, _face, _interest_filter_id, _filter_obj): # type: (Name, Interest, Face, int, InterestFilter) -> None parameter_msg = SegmentParameterMessage() try: ProtobufTlv.decode(parameter_msg, interest.name[-1].getValue()) except ValueError: self.nodata_reply(interest.name, RET_MALFORMED_COMMAND) return parameter = parameter_msg.segment_parameter prefix = Name() for compo in parameter.name.component: prefix.append(compo.decode("utf-8")) # Check operations for op in parameter.operations.components: model_name = op.model.decode("utf-8") if model_name not in self.operations_set: self.nodata_reply(interest.name, RET_NOT_SUPPORTED) return # Fetch frames for frame_id in range(parameter.start_frame, parameter.end_frame + 1): frame_name = Name(prefix).append(str(frame_id)) for op in parameter.operations.components: model_name = op.model.decode("utf-8") data_name = Name(frame_name).append(model_name) logging.info("Request processed: %s", data_name) status = ResultStatus(prefix.toUri(), model_name, Common.getNowMilliseconds()) status.status = STATUS_FETCHING status.estimated_time = status.proecess_start_time + 10.0 self.save_status(data_name, status) # Check data existence and trigger fetching process for frame_id in range(parameter.start_frame, parameter.end_frame + 1): frame_name = Name(prefix).append(str(frame_id)) if self.storage.exists(frame_name): self.on_payload(frame_name) else: self.fetcher.fetch_data(frame_name) self.nodata_reply(interest.name, RET_OK, 10.0)
def handleCommandInterests(self, prefix, interest, transport, prefixId): # TODO: verification interestName = interest.getName() if len(interestName) <= len(prefix)+4: self.log.info("Bad command interest") commandName = str(interestName[len(prefix)].getValue()) responseMessage = RepoCommandResponseMessage() if commandName == 'insert': commandParams = interestName[len(prefix)+1].getValue() commandMessage = RepoCommandParameterMessage() ProtobufTlv.decode(commandMessage, commandParams) dataName = Name() fullSchemaName = Name() for component in commandMessage.command.name.components: fullSchemaName.append(component) if component == '_': continue dataName.append(component) self.log.info("Insert request for {}".format(dataName)) responseMessage.response.status_code = 100 processId = self.currentProcessId self.currentProcessId += 1 responseMessage.response.process_id = processId else: responseMessage.response.status_code = 403 responseData = Data(interestName) responseData.setContent(ProtobufTlv.encode(responseMessage)) transport.send(responseData.wireEncode().buf()) # now send the interest out to the publisher # TODO: pendingProcesses becomes list of all processes as objects i = Interest(dataName) i.setChildSelector(1) i.setInterestLifetimeMilliseconds(4000) try: self.pendingProcesses[processId] = (dataName, 100) except NameError: pass # wasn't valid insert request else: self._insertFace.expressInterest(i, self._onInsertionDataReceived, self._onInsertionDataTimeout)
async def query_face_id(self, uri): query_filter = FaceQueryFilterMessage() query_filter.face_query_filter.uri = uri.encode('utf-8') query_filter_msg = ProtobufTlv.encode(query_filter) name = Name("/localhost/nfd/faces/query").append(Name.Component(query_filter_msg)) interest = Interest(name) interest.mustBeFresh = True interest.canBePrefix = True ret = await fetch_data_packet(self.face, interest) if not isinstance(ret, Data): return None msg = FaceStatusMessage() try: ProtobufTlv.decode(msg, ret.content) except RuntimeError as exc: logging.fatal("Decoding Error %s", exc) return None if len(msg.face_status) <= 0: return None return msg.face_status[0].face_id
def _updateDeviceCapabilities(self, interest): """ Take the received capabilities update interest and update our directory listings. """ # we assume the sender is the one who signed the interest... signature = self._policyManager._extractSignature(interest) certificateName = signature.getKeyLocator().getKeyName() senderIdentity = IdentityCertificate.certificateNameToPublicKeyName(certificateName).getPrefix(-1) self.log.info('Updating capabilities for {}'.format(senderIdentity.toUri())) # get the params from the interest name messageComponent = interest.getName().get(self.prefix.size()+1) message = UpdateCapabilitiesCommandMessage() ProtobufTlv.decode(message, messageComponent.getValue()) # we remove all the old capabilities for the sender tempDirectory = defaultdict(list) for keyword in self._directory: tempDirectory[keyword] = [cap for cap in self._directory[keyword] if not senderIdentity.match(Name(cap['name']))] # then we add the ones from the message for capability in message.capabilities: capabilityPrefix = Name() for component in capability.commandPrefix.components: capabilityPrefix.append(component) commandUri = capabilityPrefix.toUri() if not senderIdentity.match(capabilityPrefix): self.log.error("Node {} tried to register another prefix: {} - ignoring update".format( senderIdentity.toUri(),commandUri)) else: for keyword in capability.keywords: allUris = [info['name'] for info in tempDirectory[keyword]] if capabilityPrefix not in allUris: listing = {'signed':capability.needsSignature, 'name':commandUri} tempDirectory[keyword].append(listing) self._directory= tempDirectory
def _handleCertificateRequest(self, interest, transport): """ Extracts a public key name and key bits from a command interest name component. Generates a certificate if the request is verifiable. This expects an HMAC signed interest. """ message = CertificateRequestMessage() commandParamsTlv = interest.getName().get(self.prefix.size()+1) ProtobufTlv.decode(message, commandParamsTlv.getValue()) signature = HmacHelper.extractInterestSignature(interest) deviceSerial = str(signature.getKeyLocator().getKeyName().get(-1).getValue()) response = Data(interest.getName()) certData = None hmac = None try: hmac = self._hmacDevices[deviceSerial] if hmac.verifyInterest(interest): certData = self._createCertificateFromRequest(message) # remove this hmac; another request will require a new pin self._hmacDevices.pop(deviceSerial) except KeyError: self.log.warn('Received certificate request for device with no registered key') except SecurityException: self.log.warn('Could not create device certificate') else: self.log.info('Creating certificate for device {}'.format(deviceSerial)) if certData is not None: response.setContent(certData.wireEncode()) response.getMetaInfo().setFreshnessPeriod(10000) # should be good even longer else: response.setContent("Denied") if hmac is not None: hmac.signData(response) self.sendData(response, transport, False)
def onCommandData(self, interest, data): # assume it's a command response now = time.time() response = RepoCommandResponseMessage() ProtobufTlv.decode(response, data.getContent()) self.currentStatus = response.repo_command_response.status_code self.currentInsertion = response.repo_command_response.process_id logger.debug("Response status code: " + str(self.currentStatus) + ", process id: " + str(self.currentInsertion) + ", insert #" + str(response.repo_command_response.insert_num)) command_idx = self.repoPrefix.size() # we also need to keep track of the mapping from version to processID for stats commandName = interest.getName().get(command_idx).getValue().toRawStr() if commandName == 'insert check': try: versionStr = self.processIdToVersion[self.currentInsertion] if self.currentStatus == 200: stats.insertDataForVersion(versionStr, {'insert_complete': now}) self.loop.call_soon(self.kickRepo) elif self.currentStatus >= 400: self.failureCount += 1 self.loop.call_soon(self.kickRepo) else: self.loop.call_soon(self.checkInsertion, versionStr, self.currentInserion) except: logger.warn('Missing version for process ID {}'.format(self.currentInsertion)) elif commandName == 'insert': if self.currentStatus == 100: versionStr = self.versionFromCommandMessage(interest.getName().get(command_idx+1)) self.processIdToVersion[self.currentInsertion] = versionStr stats.insertDataForVersion(versionStr, {'insert_begin': now}) self.loop.call_soon(self.checkInsertion, versionStr, self.currentInsertion) else: self.failureCount += 1 self.loop.call_soon(self.kickRepo)
def onDataReceived(self, interest, data): self.log.debug('Response to {}'.format(interest.getName())) responseMessage = RepoCommandResponseMessage() ProtobufTlv.decode(responseMessage, data.getContent()) self.log.debug('Status code: {}'.format( responseMessage.response.status_code))