TEST(TryingMessageBuildTestGroup, TryingMessageFromHeaderTest) { MESSAGE *invite = CreateMessage(); ParseMessage(INCOMMING_INVITE_MESSAGE, invite); MESSAGE *trying = BuildResponse(invite, STATUS_CODE_TRYING); CONTACT_HEADER *inviteFrom = (CONTACT_HEADER *)MessageGetHeader(HEADER_NAME_FROM, invite); CONTACT_HEADER *tryingFrom = (CONTACT_HEADER *)MessageGetHeader(HEADER_NAME_FROM, trying); CHECK_TRUE(ContactHeaderMatched(inviteFrom, tryingFrom)); DestroyMessage(&trying); DestroyMessage(&invite); }
TEST(TryingMessageBuildTestGroup, TryingMessageViaTest) { MESSAGE *invite = CreateMessage(); ParseMessage(INCOMMING_INVITE_MESSAGE, invite); MESSAGE *trying = BuildResponse(invite, STATUS_CODE_TRYING); VIA_HEADER *inviteVia = (VIA_HEADER *)MessageGetHeader(HEADER_NAME_VIA, invite); VIA_HEADER *tryingVia = (VIA_HEADER *)MessageGetHeader(HEADER_NAME_VIA, trying); CHECK_TRUE(ViaHeaderMatched(inviteVia, tryingVia)); DestroyMessage(&trying); DestroyMessage(&invite); }
TEST(TryingMessageBuildTestGroup, TryingMessageCSeqTest) { MESSAGE *invite = CreateMessage(); ParseMessage(INCOMMING_INVITE_MESSAGE, invite); MESSAGE *trying = BuildResponse(invite, STATUS_CODE_TRYING); struct CSeqHeader *inviteCSeq = (struct CSeqHeader *)MessageGetHeader(HEADER_NAME_CSEQ, invite); struct CSeqHeader *tryingCSeq = (struct CSeqHeader *)MessageGetHeader(HEADER_NAME_CSEQ, trying); CHECK_TRUE(CSeqHeadersMatched(inviteCSeq, tryingCSeq)); DestroyMessage(&trying); DestroyMessage(&invite); }
TEST(TryingMessageBuildTestGroup, TryingMessageCallIdTest) { MESSAGE *invite = CreateMessage(); ParseMessage(INCOMMING_INVITE_MESSAGE, invite); MESSAGE *trying = BuildResponse(invite, STATUS_CODE_TRYING); struct CallIdHeader *inviteCallId = (struct CallIdHeader *)MessageGetHeader(HEADER_NAME_CALLID, invite); struct CallIdHeader *tryingCallId = (struct CallIdHeader *)MessageGetHeader(HEADER_NAME_CALLID, trying); CHECK_TRUE(CallIdHeaderMatched(inviteCallId, tryingCallId)); DestroyMessage(&trying); DestroyMessage(&invite); }
TEST(TryingMessageBuildTestGroup, TryingMessageToWithTagTest) { MESSAGE *invite = CreateMessage(); ParseMessage(INCOMMING_INVITE_MESSAGE_WITH_TO_TAG, invite); MESSAGE *trying = BuildResponse(invite, STATUS_CODE_TRYING); CONTACT_HEADER *inviteTo = (CONTACT_HEADER *)MessageGetHeader(HEADER_NAME_TO, invite); CONTACT_HEADER *tryingTo = (CONTACT_HEADER *)MessageGetHeader(HEADER_NAME_TO, trying); CHECK_TRUE(ContactHeaderMatched(inviteTo, tryingTo)); DestroyMessage(&trying); DestroyMessage(&invite); }
TEST(TryingMessageBuildTestGroup, TryingMessageStatusLineTest) { MESSAGE *invite = CreateMessage(); ParseMessage(INCOMMING_INVITE_MESSAGE, invite); MESSAGE *trying = BuildResponse(invite, STATUS_CODE_TRYING); struct StatusLine *status = MessageGetStatusLine(trying); CHECK_TRUE(status != NULL); STRCMP_EQUAL(SIP_VERSION, StatusLineGetSipVersion(status)); CHECK_EQUAL(100, StatusLineGetStatusCode(status)); STRCMP_EQUAL("Trying", StatusLineGetReasonPhrase(status)); DestroyMessage(&trying); DestroyMessage(&invite); }
TEST(TryingMessageBuildTestGroup, TryingMessageDesAddrtTest) { MESSAGE *trying = NULL; AccountInit(); struct UserAgent *ua = CreateUserAgent(0); struct Dialog *dialog = AddDialog(NULL_DIALOG_ID, ua); MESSAGE *invite = BuildInviteMessage(dialog, (char *)"88002"); trying = BuildResponse(invite, STATUS_CODE_TRYING); STRCMP_EQUAL(AccountGetProxyAddr(GetAccount(0)),GetMessageAddr(trying)); DestroyMessage(&trying); DestroyMessage(&invite); ClearDialogManager(); ClearAccountManager(); DestroyUserAgent(&ua); }
void DialogOk(struct Dialog *dialog) { struct DialogId *id = GetDialogId(dialog); MESSAGE *message = BuildResponse(GetTransactionRequest(dialog->transaction), STATUS_CODE_OK); dialog->remoteSeqNumber = MessageGetCSeqNumber(GetTransactionRequest(dialog->transaction)); if (GetDialogState(dialog) == DIALOG_STATE_NON_EXIST) { SetLocalTag(id, MessageGetToTag(message)); SetDialogState(dialog, DIALOG_STATE_CONFIRMED); SetLocalSeqNumber(dialog, MessageGetCSeqNumber(message)); dialog->session = CreateSession(); } else if (GetDialogState(dialog) == DIALOG_STATE_CONFIRMED) { if (DialogGetRequestMethod(dialog) == SIP_METHOD_BYE) { SetDialogState(dialog, DIALOG_STATE_TERMINATED); } } ResponseWith(dialog->transaction, message, TRANSACTION_SEND_OK); }
BOOL TmHandleRequestMessage(MESSAGE *message) { struct Transaction *t = MatchRequest(message); SIP_METHOD method = MessageGetMethod(message); if (!t) { OnTransactionEvent(NULL, TRANSACTION_EVENT_NEW, message); } else { if (method == SIP_METHOD_INVITE) { RunFsm(t, TRANSACTION_EVENT_INVITE); DestroyMessage(&message); } else if (method == SIP_METHOD_CANCEL) { struct Dialog *d = (struct Dialog *)GetTransactionUser(t); struct Message *rt = BuildResponse(message, 487); OnTransactionEvent(d, TRANSACTION_EVENT_CANCELED, message); ResponseWith(t, rt, TRANSACTION_SEND_REQUEST_TERMINATED); OnTransactionEvent(NULL, TRANSACTION_EVENT_NEW, message); } } return TRUE; }
Boolean C1222Server_ProcessMeterMessage(C1222Server* pServer, ACSE_Message* pMsg, ACSE_Message* pResponseMessage) { Unsigned16 tagIndex; Unsigned16 tagLength; Epsem epsem; Unsigned8 responseMode; Epsem responseEpsem; C1222AL* pAppLayer; Boolean wantMac; Boolean wantAuthenticate; Boolean wantMacIn; Unsigned8 keyId = 0; Unsigned8 key[24]; Unsigned8 cipher; Unsigned8 iv[8]; Unsigned8 ivLength; Unsigned16 userId; Unsigned8 password[20]; Boolean errorResponse; Boolean isNotification; Boolean isTest; Unsigned16 sequence; Unsigned8* buffer; Unsigned16 length; C1222MessageFailureCode reason; C1222StandardVersion requestStandard; C1219TableServer_GetClientUserAndPassword(pServer->pTableServer, &userId, password); pAppLayer = &(pServer->pStack->Xapplication); requestStandard = ACSE_Message_GetStandardVersion(pMsg); if ( !ACSE_Message_GetCallingApInvocationId(pMsg, &sequence) ) sequence = 0; C1222AL_LogComEventAndBytes(pAppLayer, COMEVENT_C1222_RECEIVED_REQUEST, &sequence, sizeof(sequence)); // if there are no keys in the meter, c12.22 gets client password #ifdef C1222_INCLUDE_DEVICE if ( C1222AL_GetNumberOfKeys(pAppLayer) > 0 ) { // if there is no password in the meter, it should probably still work memset(password, 0, sizeof(password)); } #endif // C1222_INCLUDE_DEVICE wantMac = wantMacIn = ACSE_Message_IsEncrypted(pMsg); wantAuthenticate = ACSE_Message_IsAuthenticated(pMsg); isNotification = ACSE_Message_IsNotification(pMsg); isTest = ACSE_Message_IsTest(pMsg); // if this message is a response, based on the presence of a called ap invocation id, // ignore it with no response to avoid getting into a ping-pong match with the // comm module (actually happened). // What happened before is that the optical port initiated a rflan table read which // timed out, but then the response finally came in. Since the response had timed out // the client routine to handle responses did not take the message, so it got passed to // the server. The response was ignored in the acse message, but that left an empty // message (no information content) that was sent to the rflan. The rflan also processed // this and returned an empty response to it, etc. if ( ACSE_Message_GetCalledApInvocationId(pMsg, &sequence) ) { pServer->processMessageResponse = C1222RESPONSE_OK; // this prevents sending a message return FALSE; } // place the response epsem at the end of the message buffer pServer->responseEpsemBuffer = &pResponseMessage->buffer[MAX_ACSE_OVERHEAD_LENGTH]; // to allow working with tables test bench, need an option to respond using the same // key as was used in the request // for now, just do that always // if encrypted or authenticated, get info needed to encrypt or authenticate, // plus user info to establish access rights #ifdef C1222_INCLUDE_DEVICE if ( wantMac || wantAuthenticate ) { if ( !ACSE_Message_GetEncryptionKeyId(pMsg, &keyId) ) keyId = 0; if ( C1222AL_GetKey(pAppLayer, keyId, &cipher, key) ) { // to decode the user info we need the iv in the sent message if ( !ACSE_Message_GetIV(pMsg, iv, &ivLength) ) { ivLength = 4; memset(iv, 0, ivLength); // if none sent assume zero iv } if ( !ACSE_Message_GetUserInfo(pMsg, key, cipher, iv, ivLength, &userId, password, pAppLayer->tempBuffer) ) { // the request message has either passed decryption or authentication // if no user info is in the message, assume default values C1219TableServer_GetClientUserAndPassword(pServer->pTableServer, &userId, password); } // now set up to encrypt / authenticate the response message ivLength = 4; C1222Misc_RandomizeBuffer(iv, ivLength); } else // if we don't have the keyid they asked for, can't encrypt or authenticate { wantMac = wantAuthenticate = FALSE; } } // end if want encryption or authentication #else // avoid some warnings in the comm module ivLength = 4; cipher = 0; #endif // C1222_INCLUDE_DEVICE // find the app-data in the request message if ( ACSE_Message_GetApData(pMsg, &buffer, &length) ) { if ( pMsg->standardVersion == CSV_MARCH2006 && wantMacIn ) { tagIndex = 2; // skip the mac at the start of the buffer tagLength = length - 2; } else { tagIndex = 0; tagLength = length; if ( wantMacIn ) tagLength -= (Unsigned16)2; // skip the crc at the end of the apdata } // if the message is encrypted, the user information includes a <mac> before the <epsem> Epsem_Init(&epsem, &buffer[tagIndex], tagLength); if ( Epsem_Validate(&epsem) ) { responseMode = Epsem_GetResponseMode(&epsem); errorResponse = ProcessEpsemRequests(pServer, &epsem, userId, password, isTest, isNotification, &responseEpsem, requestStandard); // now that the epsem response is set up, start the response message if ( (responseMode == C1222RESPOND_ALWAYS) || ((responseMode == C1222RESPOND_ONEXCEPTION) && errorResponse) ) { return BuildResponse(pServer, pMsg, &responseEpsem, pResponseMessage, pAppLayer, wantMac, wantAuthenticate, keyId, iv, ivLength, cipher, key); } // else no response needed pServer->processMessageResponse = C1222RESPONSE_OK; } // end if the epsem validated else { reason = MFC_RECEIVED_EPSEM_INVALID; C1222AL_LogComEventAndBytes(pAppLayer, COMEVENT_C1222_SEND_RESPONSE_FAILED, &reason, sizeof(reason)); // invalid epsem in request pServer->processMessageResponse = C1222RESPONSE_IAR; //this will cause an iar response to be sent } } // end if found the information element else { reason = MFC_RECEIVED_INFORMATION_ELEMENT_MISSING; C1222AL_LogComEventAndBytes(pAppLayer, COMEVENT_C1222_SEND_RESPONSE_FAILED, &reason, sizeof(reason)); // missing info element pServer->processMessageResponse = C1222RESPONSE_IAR; // this will cause an iar to be sent } return FALSE; }
/// Returns a string containing a valid HTTP 1.0 or 1.1 response, ready for sending. /// The response is partly build from internal variables set before this call is made. /// To be precise, protocol, headers and body are used. /// \return A string containing a valid HTTP 1.0 or 1.1 response, ready for sending. /// This function calls this->BuildResponse(this->method,this->url) std::string & HTTP::Parser::BuildResponse() { return BuildResponse(method,url); }