void athena_ProcessMessage(Athena *athena, CCNxMetaMessage *ccnxMessage, PARCBitVector *ingressVector) { if (ccnxMetaMessage_IsInterest(ccnxMessage)) { const char *name = ccnxName_ToString(ccnxInterest_GetName(ccnxMessage)); parcLog_Debug(athena->log, "Processing Interest Message: %s", name); parcMemory_Deallocate(&name); CCNxInterest *interest = ccnxMetaMessage_GetInterest(ccnxMessage); _processInterest(athena, interest, ingressVector); athena->stats.numProcessedInterests++; } else if (ccnxMetaMessage_IsContentObject(ccnxMessage)) { const char *name = ccnxName_ToString(ccnxContentObject_GetName(ccnxMessage)); parcLog_Debug(athena->log, "Processing Content Object Message: %s", name); parcMemory_Deallocate(&name); CCNxContentObject *contentObject = ccnxMetaMessage_GetContentObject(ccnxMessage); _processContentObject(athena, contentObject, ingressVector); athena->stats.numProcessedContentObjects++; } else if (ccnxMetaMessage_IsControl(ccnxMessage)) { parcLog_Debug(athena->log, "Processing Control Message"); CCNxControl *control = ccnxMetaMessage_GetControl(ccnxMessage); _processControl(athena, control, ingressVector); athena->stats.numProcessedControlMessages++; } else if (ccnxMetaMessage_IsInterestReturn(ccnxMessage)) { parcLog_Debug(athena->log, "Processing Interest Return Message"); CCNxInterestReturn *interestReturn = ccnxMetaMessage_GetInterestReturn(ccnxMessage); _processInterestReturn(athena, interestReturn, ingressVector); athena->stats.numProcessedInterestReturns++; } else { trapUnexpectedState("Invalid CCNxMetaMessage type"); } }
static bool _ccnxPortalRTA_IsConnected(CCNxPortal *portal) { bool result = false; CCNxMetaMessage *response; if ((response = ccnxPortal_Receive(portal, CCNxStackTimeout_Never)) != NULL) { if (ccnxMetaMessage_IsControl(response)) { CCNxControl *control = ccnxMetaMessage_GetControl(response); if (ccnxControl_IsNotification(control)) { NotifyStatus *status = ccnxControl_GetNotifyStatus(control); if (notifyStatus_IsConnectionOpen(status) == true) { result = true; } notifyStatus_Release(&status); } } ccnxMetaMessage_Release(&response); } return result; }
static bool _ccnxPortalRTA_Ignore(void *privateData, const CCNxName *name, const CCNxStackTimeout *microSeconds) { CCNxControl *control = ccnxControl_CreateRemoveRouteToSelfRequest(name); CCNxMetaMessage *message = ccnxMetaMessage_CreateFromControl(control); ccnxControl_Release(&control); bool result = _ccnxPortalRTA_Send(privateData, message, CCNxStackTimeout_Never); // There is a problem here if the client invokes this function on a portal that is already receiving messages. // This simply absorbs messages until the receipt of the acknowledgement of this listen. // Perhaps what should happen is not read any messages and let the client sort it out in its read loop. if (result == true) { CCNxMetaMessage *response = _ccnxPortalRTA_Receive(privateData, microSeconds); if (response != NULL) { if (ccnxMetaMessage_IsControl(response)) { // TODO: Check that the response was success. result = true; } ccnxMetaMessage_Release(&response); } else { // We got a NULL reponse (possibly due to timeout). Since we always expect a // response from the forwarder, consider this a failure. result = false; } } ccnxMetaMessage_Release(&message); return result; }
LONGBOW_TEST_CASE(Global, athena_ProcessControl_CPI_REGISTER_PREFIX) { PARCURI *connectionURI; Athena *athena = athena_Create(100); CCNxName *name = ccnxName_CreateFromCString("ccnx:/foo/bar"); CCNxControl *control = ccnxControl_CreateAddRouteToSelfRequest(name); // CPI_REGISTER_PREFIX CCNxMetaMessage *registerPrefixCommand = ccnxMetaMessage_CreateFromControl(control); ccnxControl_Release(&control); control = ccnxControl_CreateRemoveRouteToSelfRequest(name); // CPI_UNREGISTER_PREFIX CCNxMetaMessage *unregisterPrefixCommand = ccnxMetaMessage_CreateFromControl(control); ccnxControl_Release(&control); ccnxName_Release(&name); connectionURI = parcURI_Parse("tcp://localhost:50100/listener/name=TCPListener"); const char *result = athenaTransportLinkAdapter_Open(athena->athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); connectionURI = parcURI_Parse("tcp://localhost:50100/name=TCP_0"); result = athenaTransportLinkAdapter_Open(athena->athenaTransportLinkAdapter, connectionURI); assertTrue(result != NULL, "athenaTransportLinkAdapter_Open failed (%s)", strerror(errno)); parcURI_Release(&connectionURI); int linkId = athenaTransportLinkAdapter_LinkNameToId(athena->athenaTransportLinkAdapter, "TCP_0"); PARCBitVector *ingressVector = parcBitVector_Create(); parcBitVector_Set(ingressVector, linkId); // Call _Receive() once to prime the link. Messages are dropped until _Receive() is called once. PARCBitVector *linksRead = NULL; CCNxMetaMessage *msg = athenaTransportLinkAdapter_Receive(athena->athenaTransportLinkAdapter, &linksRead, -1); assertNull(msg, "Expected to NOT receive a message after the first call to _Receive()"); CCNxMetaMessage *cpiMessages[2]; cpiMessages[0] = registerPrefixCommand; // CPI_REGISTER_PREFIX cpiMessages[1] = unregisterPrefixCommand; // CPI_UNREGISTER_PREFIX for (int i = 0; i < 2; i++) { CCNxMetaMessage *cpiMessageToSend = cpiMessages[i]; athena_ProcessMessage(athena, cpiMessageToSend, ingressVector); ccnxMetaMessage_Release(&cpiMessageToSend); CCNxMetaMessage *ack = athenaTransportLinkAdapter_Receive(athena->athenaTransportLinkAdapter, &linksRead, -1); assertNotNull(ack, "Expected a CPI_ACK message back"); assertTrue(ccnxMetaMessage_IsControl(ack), "Expected a control message back"); parcBitVector_Release(&linksRead); PARCJSON *json = ccnxControl_GetJson(ack); const PARCJSONValue *cpiAckResult = parcJSON_GetByPath(json, "CPI_ACK/REQUEST/RESULT"); bool commandResult = parcJSONValue_GetBoolean(cpiAckResult); assertTrue(commandResult, "Expected the ACK to contain RESULT=true"); ccnxMetaMessage_Release(&ack); } parcBitVector_Release(&ingressVector); athena_Release(&athena); }
LONGBOW_TEST_CASE(Global, ccnxMetaMessage_IsInterest) { CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar"); CCNxInterest *interest = ccnxInterest_CreateSimple(name); CCNxMetaMessage *portalMessage = ccnxMetaMessage_CreateFromInterest(interest); assertTrue(ccnxMetaMessage_IsInterest(portalMessage), "Expected portal message to be an Interest"); assertFalse(ccnxMetaMessage_IsContentObject(portalMessage), "Did not expect portal message to be a ContentObject"); assertFalse(ccnxMetaMessage_IsControl(portalMessage), "Did not expect portal message to be a Control message"); ccnxMetaMessage_Release(&portalMessage); ccnxInterest_Release(&interest); ccnxName_Release(&name); }
LONGBOW_TEST_CASE(Global, ccnxMetaMessage_IsContentObject) { CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar"); PARCBuffer *payload = parcBuffer_WrapCString("This is some data. It's not good data, but it is data."); CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload); CCNxMetaMessage *portalMessage = ccnxMetaMessage_CreateFromContentObject(contentObject); assertTrue(ccnxMetaMessage_IsContentObject(portalMessage), "Expected portal message to be an ContentObject"); assertFalse(ccnxMetaMessage_IsInterest(portalMessage), "Did not expect portal message to be an Interest"); assertFalse(ccnxMetaMessage_IsControl(portalMessage), "Did not expect portal message to be a Control message"); ccnxMetaMessage_Release(&portalMessage); ccnxContentObject_Release(&contentObject); parcBuffer_Release(&payload); ccnxName_Release(&name); }