static DVM_TypeSpecifier * copy_type_specifier(TypeSpecifier *src) { DVM_TypeSpecifier *dest; int derive_count = 0; TypeDerive *derive; int param_count; int i; dest = MEM_malloc(sizeof(DVM_TypeSpecifier)); dest->basic_type = src->basic_type; for (derive = src->derive; derive; derive = derive->next) { derive_count++; } dest->derive_count = derive_count; dest->derive = MEM_malloc(sizeof(DVM_TypeDerive) * derive_count); for (i = 0, derive = src->derive; derive; derive = derive->next, i++) { switch (derive->tag) { case DVM_FUNCTION_DERIVE: dest->derive[i].tag = DVM_FUNCTION_DERIVE; dest->derive[i].u.function_d.parameter = copy_parameter_list(derive->u.function_d.parameter_list, ¶m_count); dest->derive[i].u.function_d.parameter_count = param_count; break; default: DBG_assert(0, ("derive->tag..%d\n", derive->tag)); } } return dest; }
//------------------------------------------------------------------------- // FUNCTION : NdpAddDataToNeighborCache() // // PURPOSE : Adding data to neighbor cache // // PARAMETERS : neighborCache - pointer to neighbor cache // neighborData - neighbor data to be added // // RETURN VALUE : None //------------------------------------------------------------------------- static void NdpAddDataToNeighborCache( NdpNeighborTable* neighborCache, NdpNeighborStruct* neighborData) { if (neighborCache && neighborData) { if (neighborCache->numEntry == neighborCache->maxEntry) { unsigned int newNeighborCacheSize = (unsigned int) ((neighborCache->numEntry + NDP_INITIAL_CACHE_ENTRY) * sizeof(NdpNeighborStruct)); NdpNeighborStruct* tempCache = (NdpNeighborStruct*) MEM_malloc(newNeighborCacheSize); memset(tempCache, 0, newNeighborCacheSize); memcpy(tempCache, neighborCache->neighborTable, (sizeof(NdpNeighborStruct) * neighborCache->numEntry)); MEM_free(neighborCache->neighborTable); neighborCache->neighborTable = tempCache; neighborCache->maxEntry = neighborCache->numEntry + NDP_INITIAL_CACHE_ENTRY; } memcpy(&(neighborCache->neighborTable[neighborCache->numEntry]), neighborData, sizeof(NdpNeighborStruct)); neighborCache->numEntry++; }// end if (neighborCache && neighborData) }
DVM_Char * dkc_expression_to_string(Expression *expr) { char buf[LINE_BUF_SIZE]; DVM_Char wc_buf[LINE_BUF_SIZE]; int len; DVM_Char *new_str; if (expr->kind == BOOLEAN_EXPRESSION) { if (expr->u.boolean_value) { dvm_mbstowcs("true", wc_buf); } else { dvm_mbstowcs("false", wc_buf); } } else if (expr->kind == INT_EXPRESSION) { sprintf(buf, "%d", expr->u.int_value); dvm_mbstowcs(buf, wc_buf); } else if (expr->kind == DOUBLE_EXPRESSION) { sprintf(buf, "%f", expr->u.double_value); dvm_mbstowcs(buf, wc_buf); } else if (expr->kind == STRING_EXPRESSION) { return expr->u.string_value; } else { return NULL; } len = dvm_wcslen(wc_buf); new_str = MEM_malloc(sizeof(DVM_Char) * (len + 1)); dvm_wcscpy(new_str, wc_buf); return new_str; }
DVM_ExecutableList * DKC_compile(DKC_Compiler *compiler, FILE *fp, char *path) { extern FILE *yyin; DVM_ExecutableList *list; DVM_Executable *exe; DBG_assert(st_compiler_list == NULL, ("st_compiler_list != NULL(%p)", st_compiler_list)); set_path_to_compiler(compiler, path); compiler->input_mode = FILE_INPUT_MODE; yyin = fp; list = MEM_malloc(sizeof(DVM_ExecutableList)); list->list = NULL; exe = do_compile(compiler, list, NULL, DVM_FALSE); exe->path = MEM_strdup(path); list->top_level = exe; /* dvm_disassemble(exe);*/ dispose_compiler_list(); dkc_reset_string_literal_buffer(); return list; }
static CRB_Value call_native_function(CRB_Interpreter *inter, LocalEnviroment *env, Exprssion *expr, CRB_NativeFunctionProc *proc) { CRB_Value value; int arg_count; ArgumentList *arg_p; CRB_Value *args; int i; for(arg_count = 0, arg_p = expr->u.function_call_expression.argument; arg_p;arg_p = arg_p->next){ arg_count++; } arg = MEM_malloc(sizeof(CRB_Value) * arg_count); for(arg_p = expr->u.function_call_expression.argument, i = 0; arg_p; arg_p = arg_p->next, i++){ args[i] = eval_expression(inter, env, arg_p->next); } val = proc(inter, arg_count, args); for( i = 0;i < arg_count;i++){ release_if_string(&args[i]); } MEM_free(args); return value; }
char * minic_package_name_to_string(PackageName *src) { int len = 0; PackageName *pos; char *dest; if (src == NULL) { return NULL; } for (pos = src; pos; pos = pos->next) { len += strlen(pos->name) + 1; } dest = (char *)MEM_malloc(len); dest[0] = '\0'; for (pos = src; pos; pos = pos->next) { strcat(dest, pos->name); if (pos->next) { strcat(dest, "."); } } return dest; }
static void add_static_variables(MVM_VirtualMachine *mvm, MVM_Executable *exe) { int i; MVM_Class *pos = exe->class_definition; mvm->static_v.variable = MEM_malloc(sizeof(MVM_Value) * exe->global_variable_count); mvm->static_v.variable_count = exe->global_variable_count; for (i = 0; i < exe->global_variable_count; i++) { if (exe->global_variable[i].type->basic_type == MVM_STRING_TYPE) { mvm->static_v.variable[i].object = NULL; } else if(exe->global_variable[i].type->basic_type == MVM_CLASS_TYPE) { mvm->static_v.variable[i].object = malloc(sizeof(MVM_Object)); mvm->static_v.variable[i].object->type = CLASS_OBJECT; mvm->static_v.variable[i].object->u.class_object.field_count = exe->class_definition->field_count; mvm->static_v.variable[i].object->u.class_object.field = malloc(sizeof(MVM_Value)*exe->class_definition->field_count); } } for (i = 0; i < exe->global_variable_count; i++) { initialize_value(mvm, exe->global_variable[i].type, &mvm->static_v.variable[i]); } }
static MVM_Object * chain_string(MVM_VirtualMachine *mvm, MVM_Object *str1, MVM_Object *str2) { int result_len; MVM_Char *left; MVM_Char *right; MVM_Char *result; MVM_Object *ret; if (str1 == NULL) { left = NULL_STRING; } else { left = str1->u.string.string; } if (str2 == NULL) { right = NULL_STRING; } else { right = str2->u.string.string; } result_len = strlen(left) +strlen(right); result = MEM_malloc(sizeof(MVM_Char) * (result_len + 1)); strcpy(result, left); strcat(result, right); ret = mvm_create_mvm_string_i(mvm, result); return ret; }
static DVM_Boolean add_exe_to_list(DVM_Executable *exe, DVM_ExecutableList *list) { DVM_ExecutableItem *new_item; DVM_ExecutableItem *pos; DVM_ExecutableItem *tail; for (pos = list->list; pos; pos = pos->next) { if (dvm_compare_package_name(pos->executable->package_name, exe->package_name) && pos->executable->is_required == exe->is_required) { return DVM_FALSE; } tail = pos; } new_item = MEM_malloc(sizeof(DVM_ExecutableItem)); new_item->executable = exe; new_item->next = NULL; if (list->list == NULL) { list->list = new_item; } else { tail->next = new_item; } return DVM_TRUE; }
static char* str_alloc(char* src) { int len = strlen(src) + 1; char* ret = MEM_malloc(sizeof(char) * (len+1)); strcpy(ret, src); return ret; }
void STAT_AggregatedSum::Serialize(clocktype now, char** data, int* size) { *data = (char*) MEM_malloc(sizeof(STAT_SimpleAggregationData)); *size = sizeof(STAT_SimpleAggregationData); STAT_SimpleAggregationData* agg = (STAT_SimpleAggregationData*) *data; agg->m_Value = m_Value; agg->m_NumDataPoints = m_NumDataPoints; }
/* サイズsizeの配列をヒープ領域へ割り当てる. 要素の初期化は特に行わず, 呼んだ側で頑張ってもらう */ LL1LL_Object* alloc_array(size_t size) { /* 領域確保 */ LL1LL_Object *new_entry = (LL1LL_Object *)MEM_malloc(sizeof(LL1LL_Object)); /* オブジェクトの種類と, マークの初期化 */ new_entry->type = ARRAY_OBJECT; new_entry->marked = LL1LL_FALSE; /* 配列として, LL1LL_Valueの配列を動的に確保する */ new_entry->u.ary.array_value = (LL1LL_Value *)MEM_malloc(sizeof(LL1LL_Value) * size); /* サイズ設定 */ new_entry->u.ary.size = size; new_entry->u.ary.alloc_size = size * sizeof(LL1LL_Value); /* TODO:これは正しくない(配列の配列の場合は, 要素の配列のサイズも加算しなくてはいけない)が, 今のところ問題にはなっていない */ /* ヒープ管理リストに追加 */ addHeapEntry(new_entry); return new_entry; }
// Copyright (c) 2001-2013, SCALABLE Network Technologies, Inc. All Rights Reserved. // 600 Corporate Pointe // Suite 1200 // Culver City, CA 90230 // [email protected] // // This source code is licensed, not sold, and is subject to a written // license agreement. Among other things, no portion of this source // code may be copied, transmitted, disclosed, displayed, distributed, // translated, used as the basis for a derivative work, or used, in // whole or in part, for any program or purpose other than its intended // use in compliance with the license agreement as part of the QualNet // software. This source code and certain of the algorithms contained // within it are confidential trade secrets of Scalable Network // Technologies, Inc. and may not be used as the basis for any other // software, hardware, product or service. // /** // PROTOCOL :: SIP // LAYER : APPLICATION // REFERENCES :: // + whatissip.pdf : www.sipcenter.com // + SIP-2003-Future_of_SIP_and_Presence.pdf // + siptutorial.pdf // COMMENTS :: This is implementation of SIP 2.0 as per RFC 3261 // **/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "api.h" #include "app_util.h" #include "multimedia_sipmsg.h" #include "multimedia_sipdata.h" #define DEBUG 0 // /** // FUNCTION :: SipMsg // LAYER :: APPLICATION // PURPOSE :: Constructor of the SipMsg class // PARAMETERS :: // RETURN :: NULL // **/ SipMsg :: SipMsg() { msgType = SIP_INVALID_MSG; requestType = INVALID_REQ; responseType = INVALID_RES; contentLength = 0; pBuffer = NULL; pLength = 0; totHdrLen = 0; maxForwards = SIP_MAX_FORWARDS; ackType = SIP_ACK_INVALID; connectionId = INVALID_ID; proxyConnectionId = INVALID_ID; fromIp = INVALID_ADDRESS; targetIp = INVALID_ADDRESS; memset(targetUrl , 0, sizeof(targetUrl)); via = NULL; maxViaCount = SIP_VIA_COUNT; viaCount = 0; next = NULL; memset(from, 0, sizeof(from)); memset(to, 0, sizeof(to)); memset(callId, 0, sizeof(callId)); memset(tagTo, 0, sizeof(tagTo)); memset(tagFrom, 0, sizeof(tagFrom)); memset(cSeq, 0, sizeof(cSeq)); memset(cSeqMsg, 0, sizeof(cSeqMsg)); memset(contact, 0, sizeof(contact)); memset(contentType, 0, sizeof(contentType)); memset(domainName, 0, sizeof(domainName)); memset(transProto, 0, sizeof(transProto)); memset(callInfo, 0, sizeof(callInfo)); } // /** // FUNCTION :: SipMsg // LAYER :: APPLICATION // PURPOSE :: Destructor of the SipMsg class // PARAMETERS :: // RETURN :: NULL // **/ SipMsg :: ~SipMsg() { if (via != NULL) { MEM_free(via); } via = NULL; } // /** // FUNCTION :: SipGenerateVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +viaGen : char* : Field to be filled up // +start : int : starting address // +isBye : bool : true for a BYE message // RETURN :: void : NULL // **/ void SipMsg :: SipGenerateVia(char* viaGen, int start, bool isBye) { // count refers to no of vias int count = start; int storedCount = 0; int offset = 0; while (count < viaCount) { if (via[count].isReceivedIp && !isBye) { storedCount = sprintf(viaGen + offset, "Via: SIP/2.0/%s %s;branch=%s;received=%s\r\n", transProto, via[count].viaProxy, via[count].branch, via[count].receivedIp); offset += storedCount; } else { storedCount = sprintf(viaGen + offset, "Via: SIP/2.0/%s %s;branch=%s\r\n", transProto, via[count].viaProxy, via[count].branch); offset += storedCount; } count++; } } // /** // FUNCTION :: SipGenViaWithOwnVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +localVia : char* : Field to be filled up // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipGenViaWithOwnVia(char* localVia, SipData* sip) { char branch[SIP_STR_SIZE16]; char via[SIP_VIA_COUNT * MAX_STRING_LENGTH]; ERROR_Assert(localVia, "Via field cannot be NULL\n"); sip->SipGenerateBranch(branch); sprintf(via, "Via: SIP/2.0/%s %s;branch=%s\r\n", transProto, sip->SipGetFQDN(), branch); SipGenerateVia(via + strlen(via)); memcpy(localVia, via, strlen(via)); } // /** // FUNCTION :: SipGenViaWithoutTopVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +localVia : char* : Field to be filled up // RETURN :: void : NULL // **/ void SipMsg :: SipGenViaWithoutTopVia(char* localVia) { // routine assumes via parsing is already done and // therefore viaCount contains the numb of vias present ERROR_Assert(localVia, "localVia field cannot be NULL\n"); SipGenerateVia(localVia, 1); } // /** // FUNCTION :: SipUpdateViaWithReceivedIp // LAYER :: APPLICATION // PURPOSE :: Update via field with the received Ip // PARAMETERS :: // RETURN :: void : NULL // **/ void SipMsg :: SipUpdateViaWithReceivedIp() { char recdIpStr[SIP_STR_SIZE16]; if (viaCount < 1) { // no via available return; } IO_ConvertIpAddressToString(fromIp, recdIpStr); strcpy(via[0].receivedIp, recdIpStr); via[0].isReceivedIp = true; } // /** // FUNCTION :: SipGetResponseString // LAYER :: APPLICATION // PURPOSE :: Get the respone string corresponding to an enum // PARAMETERS :: // +responseType : SipResType : Response type // +responseStr : char* : string to be filled up // RETURN :: void : NULL // **/ void SipMsg :: SipGetResponseString(SipResType responseType, char* responseStr) { switch (responseType) { case TRYING: strcpy(responseStr, "Trying"); break; case RINGING: strcpy(responseStr, "Ringing"); break; case OK: strcpy(responseStr, "OK"); break; default: strcpy(responseStr, ""); } } // /** // FUNCTION :: SipCreateInviteRequestPkt // LAYER :: APPLICATION // PURPOSE :: Create Sip Invite request packet // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // +voip : VoipHostData*: Pointer to VoipHostData // RETURN :: void : NULL // **/ void SipMsg :: SipCreateInviteRequestPkt(Node* node, SipData* sip, VoipHostData* voip) { char protoBuf[SIP_STR_SIZE16]; char branch[MAX_STRING_LENGTH]; char callId[SIP_STR_SIZE64]; char tag[SIP_STR_SIZE16]; char myIPAddress[MAX_STRING_LENGTH]; char aliasAddr[MAX_ALIAS_ADDR_SIZE]; Address addr; Int32 i = -1; if (sip->SipGetTransProtocolType() == TCP) { strcpy(protoBuf, "TCP"); } else if (sip->SipGetTransProtocolType() == UDP) { strcpy(protoBuf, "UDP"); } pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); do { i++; aliasAddr[i] = voip->sourceAliasAddr[i]; }while (voip->sourceAliasAddr[i] != '@'); aliasAddr[++i] = '\0'; addr.networkType = NETWORK_IPV4; addr.interfaceAddr.ipv4 = voip->localAddr; IO_ConvertIpAddressToString(&addr , myIPAddress); sip->SipGenerateBranch(branch); sip->SipGenerateTag(node, tag); sip->SipGenerateCallIdPfx(node, callId); // Add a sample SDP for audio in SIP request msg body // Note: 1. include only the required items, and must be in order; // 2. most are hardcoded for simplicity---just as placeholders in simulation and not parsed; // 3. use fixed RTP port for simplicity---same src/dst port for RTP, so as to let wireshark recognize RTP by port char sdpRequestBuffer[BIG_STRING_LENGTH]; // buffer size 512, enough for the following SIP msg body: 116+4(port#)+FQDN memset(sdpRequestBuffer, 0, BIG_STRING_LENGTH); // This works for node with single interface---should use the sending interface IP if multiple NodeAddress connAddr = MAPPING_GetDefaultInterfaceAddressFromNodeId(node, node->nodeId); char connAddrStr[MAX_STRING_LENGTH]; memset(connAddrStr, 0, MAX_STRING_LENGTH); IO_ConvertIpAddressToString(connAddr, connAddrStr); sprintf(sdpRequestBuffer, "v=0\r\n" "o=user 8000 8000 IN IP4 %s\r\n" "s=SIP Call\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n" "m=audio %d RTP/AVP 0\r\n" "a=sendrecv\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=ptime:20\r\n", sip->SipGetFQDN(), connAddrStr, APP_RTP); unsigned int sdpRequestLength = (unsigned int)strlen(sdpRequestBuffer); sprintf(pBuffer, "INVITE %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %d INVITE\r\n" "Contact: <%s>\r\n" "Call-Info: %d\r\n" "Content-Type: application/sdp\r\n" "Content-Length: %d\r\n\r\n" "%s", // Add SDP msg body voip->destAliasAddr, protoBuf, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, voip->destAliasAddr, voip->sourceAliasAddr, tag, callId, sip->SipGenerateSeqCounter(), strcat(aliasAddr,myIPAddress), voip->callSignalPort, sdpRequestLength, // SDP msg body length sdpRequestBuffer);// SDP msg body str pLength = (unsigned int)strlen(pBuffer); // stats incremented sip->SipIncrementInviteSent(); sip->SipIncrementCallAttempted(); SipFillComponents(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s - \n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of forwarded sip - pBuffer: %d\n", pLength); } } // /** // FUNCTION :: SipCreate2xxAckRequestPkt // LAYER :: APPLICATION // PURPOSE :: create a sip Acknowledge request packet for 2xx response // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipCreate2xxAckRequestPkt(Node* node, SipData* sip) { char branch[MAX_STRING_LENGTH]; char protoBuf[SIP_STR_SIZE16]; if (sip->SipGetTransProtocolType() == TCP) { strcpy(protoBuf, "TCP"); } else if (sip->SipGetTransProtocolType() == UDP) { strcpy(protoBuf, "UDP"); } pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); sip->SipGenerateBranch(branch); sprintf(pBuffer, "ACK %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s ACK\r\n" "Content-Length: %d\r\n\r\n", to, protoBuf, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, to, tagTo, from, tagFrom, callId, cSeq, // Number must be same as the cseq# of invite being ACK 0); pLength = (unsigned int)strlen(pBuffer); sip->SipIncrementAckSent(); sip->SipIncrementCallConnected(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s - \n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of forwarded sip - pBuffer: %d\n", pLength); } } // /** // FUNCTION :: SipCreateNon2xxAckRequestPkt // LAYER :: APPLICATION // PURPOSE :: create a sip Acknowledge request packet for Non2xx response // (This ack is sent for final responses between 300 and 699) // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipCreateNon2xxAckRequestPkt(Node* node, SipData* sip) { char branch[MAX_STRING_LENGTH]; char protoBuf[SIP_STR_SIZE16]; if (sip->SipGetTransProtocolType() == TCP) { strcpy(protoBuf, "TCP"); } else if (sip->SipGetTransProtocolType() == UDP) { strcpy(protoBuf, "UDP"); } // Note: This ack must contain a single via Header,i.e.top level via. // Ref: SEC 17.1.1.3 pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); sip->SipGenerateBranch(branch); sprintf(pBuffer, "ACK %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s ACK\r\n\r\n", to, protoBuf, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, to, tagTo, from, tagFrom, callId, cSeq); pLength = (unsigned int)strlen(pBuffer); sip->SipIncrementAckSent(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s -\n%s\n", node->nodeId, clockStr, msgBuf); } } // /** // FUNCTION :: SipCreateByeRequestPkt // LAYER :: APPLICATION // PURPOSE :: Create a Bye request packet // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipCreateByeRequestPkt(Node* node, SipData* sip, SipTransactionState state) { char branch[MAX_STRING_LENGTH]; sip->SipGenerateBranch(branch); pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); // Note that sender of BYE request creates a new transaction // within the scope of current dialogue. So it genereates and // uses a new CSeq number and if it is the same node that has // issued the Invite request then from and to field values remain // unaltered else if the called node hangs up first then it // is the node that issues the BYE request and hence from and to // field aliases including tags are swapped for creation of this req. // Call Id remains the same as it is the same dlg. if (state == SIP_CLIENT) { sprintf(pBuffer, "BYE %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %d BYE\r\n" "Content-Length: %d\r\n\r\n", to, transProto, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, to, tagTo, from, tagFrom, callId, sip->SipGenerateSeqCounter(), 0); } else if (state == SIP_SERVER) { // must swap from and to fields sprintf(pBuffer, "BYE %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %d BYE\r\n" "Content-Length: %d\r\n\r\n", from, transProto, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, from, tagFrom, to, tagTo, callId, sip->SipGenerateSeqCounter(), 0); } pLength = (unsigned int)strlen(pBuffer); sip->SipIncrementByeSent(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s -\n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of sip - pBuffer being sent: %d\n", pLength); } } // /** // FUNCTION :: SipCreateResponsePkt // LAYER :: APPLICATION // PURPOSE :: Create a response packet // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // +responseType: SipResType : Sip response type // +requestType : char* : request type // RETURN :: void : NULL // **/ void SipMsg :: SipCreateResponsePkt(Node* node, SipData* sip, SipResType responseType, const char* requestType) { char via[SIP_VIA_COUNT * SIP_STR_SIZE64]; char responseStr[SIP_STR_SIZE16]; char toBuf[SIP_STR_SIZE64]; pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); memset(via, 0, SIP_VIA_COUNT * SIP_STR_SIZE64); SipGetResponseString(responseType, responseStr); if (sip->SipGetCallModel() == SipProxyRouted) { SipUpdateViaWithReceivedIp(); } switch (responseType) { case RINGING: { SipGenerateVia(via); sip->SipGenerateTag(node, tagTo); sprintf(toBuf, "To: <%s>;tag=%s\r\n", to, tagTo); break; } case OK: { if (!strcmp(requestType, "BYE")) { SipGenerateVia(via, 0, true); } else { SipGenerateVia(via); } sprintf(toBuf, "To: <%s>;tag=%s\r\n", to, tagTo); break; } case TRYING: { SipGenerateVia(via); sprintf(toBuf, "To: <%s>\r\n", to); break; } default: break; } // add msg body for 200 OK response to INVITE if (responseType == OK && !strcmp(requestType, "INVITE")) { char sdpResponseBuffer[BIG_STRING_LENGTH]; // buffer size 512, enough for the following SIP msg body: 127+4(port#)+FQDN+IP memset(sdpResponseBuffer, 0, BIG_STRING_LENGTH); // This works for node with single interface---should use the sending interface IP if multiple NodeAddress connAddr = MAPPING_GetDefaultInterfaceAddressFromNodeId(node, node->nodeId); char connAddrStr[MAX_STRING_LENGTH]; memset(connAddrStr, 0, MAX_STRING_LENGTH); IO_ConvertIpAddressToString(connAddr, connAddrStr); sprintf(sdpResponseBuffer, "v=0\r\n" "o=user 8000 8000 IN IP4 %s\r\n" "s=SIP Call\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n" "m=audio %d RTP/AVP 0\r\n" "a=sendrecv\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=ptime:20\r\n", sip->SipGetFQDN(), connAddrStr, // own IP address APP_RTP); unsigned int sdpResponseLength = (unsigned int)strlen(sdpResponseBuffer); sprintf(pBuffer, "SIP/2.0 %d %s\r\n" "%s" "%s" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s %s\r\n" "Content-Type: application/sdp\r\n" "Content-Length: %d\r\n\r\n" "%s", responseType, responseStr, via, toBuf, from, tagFrom, callId, cSeq, requestType, sdpResponseLength, sdpResponseBuffer); } else { sprintf(pBuffer, "SIP/2.0 %d %s\r\n" "%s" "%s" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s %s\r\n" "Content-Length: %d\r\n\r\n", responseType, responseStr, via, toBuf, from, tagFrom, callId, cSeq, requestType, 0); } pLength = (unsigned int)strlen(pBuffer); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s -\n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of sip - pBuffer being sent: %d\n", pLength); } } //--------------------------------------------------------------------------- // FUNCTION: SipCreate2xxOkResponsePkt() // PURPOSE: Create a 200 OK response packet // PARAMETERS: node::Pointer to the node // sip::Pointer to SipData // voip::Pointer to VoipHostData // RETURN: None. //--------------------------------------------------------------------------- void SipMsg :: SipCreate2xxOkResponsePkt(Node* node, SipData* sip, VoipHostData* voip) { char via[SIP_VIA_COUNT * SIP_STR_SIZE64]; char responseStr[SIP_STR_SIZE16]; char toBuf[SIP_STR_SIZE64]; SipResType responseType = OK; const char* requestType = "INVITE"; char myIPAddress[MAX_STRING_LENGTH]; char aliasAddr[MAX_ALIAS_ADDR_SIZE]; SipGetResponseString(responseType, responseStr); Address addr; Int32 i = -1; pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); memset(via, 0, SIP_VIA_COUNT * SIP_STR_SIZE64); if (sip->SipGetCallModel() == SipProxyRouted) { SipUpdateViaWithReceivedIp(); } do { i++; aliasAddr[i] = voip->sourceAliasAddr[i]; }while (voip->sourceAliasAddr[i] != '@'); aliasAddr[++i] = '\0'; addr.networkType = NETWORK_IPV4; //taking the fresh IP Address voip->localAddr = MAPPING_GetInterfaceAddrForNodeIdAndIntfId( node, node->nodeId, voip->clientInterfaceIndex); addr.interfaceAddr.ipv4 = voip->localAddr; IO_ConvertIpAddressToString(&addr , myIPAddress); //OK Response SipGenerateVia(via); sprintf(toBuf, "To: <%s>;tag=%s\r\n", to, tagTo); sprintf(pBuffer, "SIP/2.0 %d %s\r\n" "%s" "%s" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "Contact: <%s>\r\n" "CSeq: %s %s\r\n" "Content-Length: %d\r\n\r\n", responseType, responseStr, via, toBuf, from, tagFrom, callId, strcat(aliasAddr , myIPAddress), cSeq, requestType, 0); pLength = (unsigned int)strlen(pBuffer); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s -\n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of sip - pBuffer being sent: %d\n", pLength); } } // /** // FUNCTION :: SipIsRequestMsg // LAYER :: APPLICATION // PURPOSE :: Check the type of received sip message // PARAMETERS :: // +token1 : char* : Input buffer // RETURN :: SipMsgType : Type of Sip message // **/ SipMsgType SipMsg :: SipIsRequestMsg(char* token1) { if (!strcmp(token1, "INVITE")) { requestType = INV; } else if (!strcmp(token1, "ACK")) { requestType = ACK; } else if (!strcmp(token1, "BYE")) { requestType = BYE; } else if (!strcmp(token1, "OPTIONS")) { requestType = OPT; } else if (!strcmp(token1, "REGISTER")) { requestType = REG; } else if (!strcmp(token1, "CANCEL")) { requestType = CAN; } else { requestType = INVALID_REQ; } if (requestType == INVALID_REQ) { msgType = SIP_INVALID_MSG; } else { msgType = SIP_REQUEST; } return msgType; } // /** // FUNCTION :: SipIsResponseMsg // LAYER :: APPLICATION // PURPOSE :: Check the type of received sip message // PARAMETERS :: // +responseToken : char* : Input buffer // +resString : char* : response string // RETURN :: SipMsgType : Type of Sip message // **/ SipMsgType SipMsg :: SipIsResponseMsg(char* responseToken, char* resString) { switch (atoi(responseToken)) { case TRYING: if (strcmp(resString, "Trying")) { return SIP_INVALID_MSG; } responseType = TRYING; break; case RINGING: if (strcmp(resString, "Ringing")) { return SIP_INVALID_MSG; } responseType = RINGING; break; case OK: if (strcmp(resString, "OK")) { return SIP_INVALID_MSG; } responseType = OK; break; default: responseType = INVALID_RES; break; } if (responseType == INVALID_RES) { msgType = SIP_INVALID_MSG; } else { msgType = SIP_RESPONSE; } return msgType; } // /** // FUNCTION :: SipParseTo // LAYER :: APPLICATION // PURPOSE :: Parse the input field // PARAMETERS :: // +toField : char* : Field to be parsed // RETURN :: void : NULL // **/ void SipMsg :: SipParseTo(char* toField) { char* next; const char* delims = {" ;"}; char* token; char field1[SIP_STR_SIZE16]; char field2[SIP_STR_SIZE64]; //Incresed Array size to 32 to fix memory corruption. char field3[SIP_STR_SIZE32]; memset(field1, 0, sizeof(field1)); memset(field2, 0, sizeof(field2)); memset(field3, 0, sizeof(field3)); IO_GetDelimitedToken(field1, toField, delims, &next); IO_GetDelimitedToken(field2, next, delims, &next); token = IO_GetDelimitedToken(field3, next, delims, &next); // strip off < and > memcpy(to, field2 + 1, strlen(field2) - 2); if (token) { sscanf(field3, "tag=%s", tagTo); } } // /** // FUNCTION :: SipParseVia // LAYER :: APPLICATION // PURPOSE :: Parse the input field // PARAMETERS :: // +currVia : char* : Field to be parsed // RETURN :: void : NULL // **/ void SipMsg :: SipParseVia(char* currVia) { char token1[SIP_STR_SIZE64]; const char* delims = ";= \r\n"; char* next; if (viaCount >= maxViaCount) { maxViaCount += SIP_VIA_COUNT; SipVia* newVia = (SipVia*) MEM_malloc(sizeof(SipVia) * maxViaCount); memcpy(newVia, via, sizeof(SipVia) * viaCount); MEM_free(via); via = newVia; } // ignore version IO_GetDelimitedToken(token1, currVia, delims, &next); IO_GetDelimitedToken(token1, next, delims, &next); strcpy(transProto, token1 + strlen(token1) - 3); // get domain name IO_GetDelimitedToken(token1, next, delims, &next); strcpy(via[viaCount].viaProxy, token1); // get branch keyword IO_GetDelimitedToken(token1, next, delims, &next); if (!strcmp(token1, "branch")) { // get branch value IO_GetDelimitedToken(token1, next, delims, &next); strcpy(via[viaCount].branch, token1); } // get received keyword if any IO_GetDelimitedToken(token1, next, delims, &next); if (!strcmp(token1, "received")) { // get received value IO_GetDelimitedToken(token1, next, delims, &next); via[viaCount].isReceivedIp = true; strcpy(via[viaCount].receivedIp, token1); IO_GetDelimitedToken(token1, next, delims, &next); } else { via[viaCount].isReceivedIp = false; } viaCount++; } // /** // FUNCTION :: SipAllocateVia // LAYER :: APPLICATION // PURPOSE :: Init and allocate memory for the Via field // PARAMETERS :: // RETURN :: void : NULL // **/ void SipMsg :: SipAllocateVia() { if (via) { viaCount = 0; MEM_free(via); via = NULL; } via = (SipVia*) MEM_malloc(sizeof(SipVia) * SIP_VIA_COUNT); memset(via, 0, sizeof(SipVia) * SIP_VIA_COUNT); } // /** // FUNCTION :: SipParseField // LAYER :: APPLICATION // PURPOSE :: Parse for fields of the sip message // PARAMETERS :: // +sipField : char* : Input buffer supplied for parsing // RETURN :: void : NULL // **/ void SipMsg :: SipParseField(char* sipField) { ERROR_Assert(sipField != NULL && *sipField != '\0', "SipParseField: No data available for parsing"); // For IO_GetDelimitedToken char* next; char* token; char delims[] = {"\r\n"}; char headerField[MAX_STRING_LENGTH]; char headerName[SIP_STR_SIZE16]; int len = totHdrLen; SipAllocateVia(); memset(headerField, 0, sizeof(headerField)); memset(headerName, 0, sizeof(headerName)); token = IO_GetDelimitedToken(headerField, sipField, delims, &next); while (token && len > 0) { sscanf(headerField, "%s", headerName); len -= (int)strlen(headerField) + 2; if (!strcmp(headerName, "Via:")) { SipParseVia(headerField); } else if (!strcmp(headerName, "Max-Forwards:")) { sscanf(headerField,"Max-Forwards: %d", &maxForwards); } else if (!strcmp(headerName, "To:")) { SipParseTo(headerField); } else if (!strcmp(headerName, "From:")) { SipParseFrom(headerField); } else if (!strcmp(headerName, "CSeq:")) { sscanf(headerField,"CSeq: %s %s", cSeq, cSeqMsg); } else if (!strcmp(headerName, "Contact:")) { SipParseContact(headerField); } else if (!strcmp(headerName, "Call-ID:")) { sscanf(headerField,"Call-ID: %s", callId); } else if (!strcmp(headerName, "Call-Info:")) { sscanf(headerField,"Call-Info: %s", callInfo); } else if (!strcmp(headerName, "Content-Type:")) { sscanf(headerField,"Content-Type: %s", contentType); } else if (!strcmp(headerName, "Content-Length:")) { sscanf(headerField,"Content-Length: %d", &contentLength); } memset(headerField, 0, sizeof(headerField)); if (len <= 0) { break; } token = IO_GetDelimitedToken(headerField, next, delims, &next); } } // /** // FUNCTION :: SipParseFrom // LAYER :: APPLICATION // PURPOSE :: Parse the input field // PARAMETERS :: // +fromField : char* : Field to be parsed // RETURN :: void : NULL // **/ void SipMsg :: SipParseFrom(char* fromField) { char* next; const char* delims = " ;"; char token1[SIP_STR_SIZE32]; //Incresed Array size to 64 to fix memory corruption. char token2[SIP_STR_SIZE64]; char token3[SIP_STR_SIZE32]; IO_GetDelimitedToken(token1, fromField, delims, &next); IO_GetDelimitedToken(token2, next, delims, &next); IO_GetDelimitedToken(token3, next, delims, &next); // strip off "< and >" memcpy(from, token2 + 1, strlen(token2) - 2); // get fromTag if (token3) { sscanf(token3, "tag=%s", tagFrom); } } // /** // FUNCTION :: SipParseContact // LAYER :: APPLICATION // PURPOSE :: Parse the input field // PARAMETERS :: // +contactField : char* : Field to be parsed // RETURN :: void : NULL // **/ void SipMsg :: SipParseContact(char* contactField) { char tmpContact[MAX_STRING_LENGTH]; memset(tmpContact, 0, MAX_STRING_LENGTH); sscanf(contactField,"Contact: %s", tmpContact); memcpy(contact, tmpContact + 1, strlen(tmpContact) - 2); } // /** // FUNCTION :: SipParseFrom // LAYER :: APPLICATION // PURPOSE :: Parse the input field // PARAMETERS :: // +fromField : char* : Field to be parsed // RETURN :: void : NULL // **/ void SipMsg :: SipParseMsg(char* msgBuf, unsigned len) { char startLine[MAX_STRING_LENGTH]; char token1[SIP_STR_SIZE16]; char token2[SIP_STR_SIZE64]; char token3[SIP_STR_SIZE16]; const char* delims = {"\r\n"}; const char* delims2 = {" "}; char* next = NULL; char* next2 = NULL; pBuffer = msgBuf; pLength = len; IO_GetDelimitedToken(startLine, pBuffer, delims, &next); ERROR_Assert(next, "SipParseMsg(): End of Line is missing in SIP msg"); // Use empty line between headers and body to extract headers const char* emptyLine = {"\r\n\r\n"}; char* endOfHeader = NULL; endOfHeader = strstr(pBuffer, emptyLine); ERROR_Assert(endOfHeader, "The empty Line after SIP headers is missing\n"); totHdrLen = (unsigned)(endOfHeader - next); IO_GetDelimitedToken(token1, startLine, delims2, &next2); IO_GetDelimitedToken(token2, next2, delims2, &next2); IO_GetDelimitedToken(token3, next2, delims2, &next2); if ((SipIsRequestMsg(token1) == SIP_REQUEST) || (SipIsResponseMsg(token2, token3) == SIP_RESPONSE)) { char headers[BIG_STRING_LENGTH]; char* startOfHeader = next + 2; strncpy(headers, startOfHeader, totHdrLen); headers[totHdrLen] = '\0'; // manually null terminated for c str SipParseField(headers); } } // /** // FUNCTION :: SipFillComponents // LAYER :: APPLICATION // PURPOSE :: Parse sip message to fill components // PARAMETERS :: // RETURN :: void : NULL // **/ void SipMsg :: SipFillComponents() { ERROR_Assert(pBuffer, "Invalid data in Buffer"); // Use empty line between headers and body to extract headers char headers[BIG_STRING_LENGTH]; const char* endOfLine = {"\r\n"}; const char* emptyLine = {"\r\n\r\n"}; char* endOfStartLine = NULL; char* endOfHeader = NULL; char* startOfHeader = NULL; endOfStartLine = strstr(pBuffer, endOfLine); ERROR_Assert(endOfStartLine, "SipFillComponents(): End of Line is missing in SIP msg"); endOfHeader = strstr(pBuffer, emptyLine); ERROR_Assert(endOfHeader, "The empty Line after SIP headers is missing\n"); totHdrLen = (unsigned)(endOfHeader - endOfStartLine); startOfHeader = endOfStartLine + 2; strncpy(headers, startOfHeader, totHdrLen); headers[totHdrLen] = '\0'; // manually null terminated for c str SipParseField(headers); } // /** // FUNCTION :: SipForwardResponsePkt // LAYER :: APPLICATION // PURPOSE :: create response packet for forwarding // PARAMETERS :: // +node : Node* : Pointer to the node // +resp : SipResType : Type of response // RETURN :: void : NULL // **/ void SipMsg :: SipForwardResponsePkt(Node* node, SipResType resp) { char responseStr[SIP_STR_SIZE16]; char currVia[SIP_VIA_COUNT * MAX_STRING_LENGTH]; memset(currVia, 0, sizeof(currVia)); SipData* sip = (SipData*)node->appData.multimedia->sigPtr; pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); SipGetResponseString(resp, responseStr); SipGenViaWithoutTopVia(currVia); sprintf(pBuffer, "SIP/2.0 %d %s\r\n" "%s" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s %s\r\n" "Contact: <%s>\r\n" "Content-Length: %d\r\n\r\n", responseType, responseStr, currVia, to, tagTo, from, tagFrom, callId, cSeq, cSeqMsg, contact, 0); pLength = (unsigned int)strlen(pBuffer); sip->SipIncrementRespForwarded(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %d forwards following message at: %s -\n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of forwarded sip - pBuffer: %d\n", pLength); } } // /** // FUNCTION :: SipForwardInviteReqPkt // LAYER :: APPLICATION // PURPOSE :: Create Invite request packet for forwarding // PARAMETERS :: // +node : Node* : Pointer to the node // RETURN :: void : NULL // **/ void SipMsg :: SipForwardInviteReqPkt(Node* node) { char currVia[SIP_VIA_COUNT * MAX_STRING_LENGTH]; memset(currVia, 0, sizeof(currVia)); SipData* sip = (SipData*) node->appData.multimedia->sigPtr; pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); // recdIp added during trying message // add own via and forward SipGenViaWithOwnVia(currVia, sip); sprintf(pBuffer, "INVITE %s SIP/2.0\r\n" "%s" "Max-Forwards: %d\r\n" "To: <%s>\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s INVITE\r\n" "Contact: <%s>\r\n" "Call-Info: %s\r\n" "Content-Type: application/sdp\r\n" "Content-Length: %d\r\n\r\n", to, currVia, maxForwards, to, from, tagFrom, callId, cSeq, contact, callInfo, 0); pLength = (unsigned int)strlen(pBuffer); // stats incremented sip->SipIncrementReqForwarded(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %d forwards following message at: %s - \n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of forwarded sip-pBuffer: %d\n", pLength); } }
// Copyright (c) 2001-2013, SCALABLE Network Technologies, Inc. All Rights Reserved. // 600 Corporate Pointe // Suite 1200 // Culver City, CA 90230 // [email protected] // // This source code is licensed, not sold, and is subject to a written // license agreement. Among other things, no portion of this source // code may be copied, transmitted, disclosed, displayed, distributed, // translated, used as the basis for a derivative work, or used, in // whole or in part, for any program or purpose other than its intended // use in compliance with the license agreement as part of the QualNet // software. This source code and certain of the algorithms contained // within it are confidential trade secrets of Scalable Network // Technologies, Inc. and may not be used as the basis for any other // software, hardware, product or service. // /** // PROTOCOL :: SIP // LAYER : APPLICATION // REFERENCES :: // + whatissip.pdf : www.sipcenter.com // + SIP-2003-Future_of_SIP_and_Presence.pdf // + siptutorial.pdf // COMMENTS :: This is implementation of SIP 2.0 as per RFC 3261 // **/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "api.h" #include "app_util.h" #include "multimedia_sipmsg.h" #include "multimedia_sipdata.h" #define DEBUG 0 // /** // FUNCTION :: SipMsg // LAYER :: APPLICATION // PURPOSE :: Constructor of the SipMsg class // PARAMETERS :: // RETURN :: NULL // **/ SipMsg :: SipMsg() { msgType = SIP_INVALID_MSG; requestType = INVALID_REQ; responseType = INVALID_RES; contentLength = 0; pBuffer = NULL; pLength = 0; totHdrLen = 0; maxForwards = SIP_MAX_FORWARDS; ackType = SIP_ACK_INVALID; connectionId = INVALID_ID; proxyConnectionId = INVALID_ID; fromIp = INVALID_ADDRESS; targetIp = INVALID_ADDRESS; memset(targetUrl , 0, sizeof(targetUrl)); via = NULL; maxViaCount = SIP_VIA_COUNT; viaCount = 0; next = NULL; memset(from, 0, sizeof(from)); memset(to, 0, sizeof(to)); memset(callId, 0, sizeof(callId)); memset(tagTo, 0, sizeof(tagTo)); memset(tagFrom, 0, sizeof(tagFrom)); memset(cSeq, 0, sizeof(cSeq)); memset(cSeqMsg, 0, sizeof(cSeqMsg)); memset(contact, 0, sizeof(contact)); memset(contentType, 0, sizeof(contentType)); memset(domainName, 0, sizeof(domainName)); memset(transProto, 0, sizeof(transProto)); memset(callInfo, 0, sizeof(callInfo)); } // /** // FUNCTION :: SipMsg // LAYER :: APPLICATION // PURPOSE :: Destructor of the SipMsg class // PARAMETERS :: // RETURN :: NULL // **/ SipMsg :: ~SipMsg() { if (via != NULL) { MEM_free(via); } via = NULL; } // /** // FUNCTION :: SipGenerateVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +viaGen : char* : Field to be filled up // +start : int : starting address // +isBye : bool : true for a BYE message // RETURN :: void : NULL // **/ void SipMsg :: SipGenerateVia(char* viaGen, int start, bool isBye) { // count refers to no of vias int count = start; int storedCount = 0; int offset = 0; while (count < viaCount) { if (via[count].isReceivedIp && !isBye) { storedCount = sprintf(viaGen + offset, "Via: SIP/2.0/%s %s;branch=%s;received=%s\r\n", transProto, via[count].viaProxy, via[count].branch, via[count].receivedIp); offset += storedCount; } else { storedCount = sprintf(viaGen + offset, "Via: SIP/2.0/%s %s;branch=%s\r\n", transProto, via[count].viaProxy, via[count].branch); offset += storedCount; } count++; } } // /** // FUNCTION :: SipGenViaWithOwnVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +localVia : char* : Field to be filled up // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipGenViaWithOwnVia(char* localVia, SipData* sip) { char branch[SIP_STR_SIZE16]; char via[SIP_VIA_COUNT * MAX_STRING_LENGTH]; ERROR_Assert(localVia, "Via field cannot be NULL\n"); sip->SipGenerateBranch(branch); sprintf(via, "Via: SIP/2.0/%s %s;branch=%s\r\n", transProto, sip->SipGetFQDN(), branch); SipGenerateVia(via + strlen(via)); memcpy(localVia, via, strlen(via)); } // /** // FUNCTION :: SipGenViaWithoutTopVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +localVia : char* : Field to be filled up // RETURN :: void : NULL // **/ void SipMsg :: SipGenViaWithoutTopVia(char* localVia) { // routine assumes via parsing is already done and // therefore viaCount contains the numb of vias present ERROR_Assert(localVia, "localVia field cannot be NULL\n"); SipGenerateVia(localVia, 1); } // /** // FUNCTION :: SipUpdateViaWithReceivedIp // LAYER :: APPLICATION // PURPOSE :: Update via field with the received Ip // PARAMETERS :: // RETURN :: void : NULL // **/ void SipMsg :: SipUpdateViaWithReceivedIp() { char recdIpStr[SIP_STR_SIZE16]; if (viaCount < 1) { // no via available return; } IO_ConvertIpAddressToString(fromIp, recdIpStr); strcpy(via[0].receivedIp, recdIpStr); via[0].isReceivedIp = true; } // /** // FUNCTION :: SipGetResponseString // LAYER :: APPLICATION // PURPOSE :: Get the respone string corresponding to an enum // PARAMETERS :: // +responseType : SipResType : Response type // +responseStr : char* : string to be filled up // RETURN :: void : NULL // **/ void SipMsg :: SipGetResponseString(SipResType responseType, char* responseStr) { switch (responseType) { case TRYING: strcpy(responseStr, "Trying"); break; case RINGING: strcpy(responseStr, "Ringing"); break; case OK: strcpy(responseStr, "OK"); break; default: strcpy(responseStr, ""); } } // /** // FUNCTION :: SipCreateInviteRequestPkt // LAYER :: APPLICATION // PURPOSE :: Create Sip Invite request packet // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // +voip : VoipHostData*: Pointer to VoipHostData // RETURN :: void : NULL // **/ void SipMsg :: SipCreateInviteRequestPkt(Node* node, SipData* sip, VoipHostData* voip) { char protoBuf[SIP_STR_SIZE16]; char branch[MAX_STRING_LENGTH]; char callId[SIP_STR_SIZE64]; char tag[SIP_STR_SIZE16]; char myIPAddress[MAX_STRING_LENGTH]; char aliasAddr[MAX_ALIAS_ADDR_SIZE]; Address addr; Int32 i = -1; if (sip->SipGetTransProtocolType() == TCP) { strcpy(protoBuf, "TCP"); } else if (sip->SipGetTransProtocolType() == UDP) { strcpy(protoBuf, "UDP"); } pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); do { i++; aliasAddr[i] = voip->sourceAliasAddr[i]; }while (voip->sourceAliasAddr[i] != '@'); aliasAddr[++i] = '\0'; addr.networkType = NETWORK_IPV4; addr.interfaceAddr.ipv4 = voip->localAddr; IO_ConvertIpAddressToString(&addr , myIPAddress); sip->SipGenerateBranch(branch); sip->SipGenerateTag(node, tag); sip->SipGenerateCallIdPfx(node, callId); // Add a sample SDP for audio in SIP request msg body // Note: 1. include only the required items, and must be in order; // 2. most are hardcoded for simplicity---just as placeholders in simulation and not parsed; // 3. use fixed RTP port for simplicity---same src/dst port for RTP, so as to let wireshark recognize RTP by port char sdpRequestBuffer[BIG_STRING_LENGTH]; // buffer size 512, enough for the following SIP msg body: 116+4(port#)+FQDN memset(sdpRequestBuffer, 0, BIG_STRING_LENGTH); // This works for node with single interface---should use the sending interface IP if multiple NodeAddress connAddr = MAPPING_GetDefaultInterfaceAddressFromNodeId(node, node->nodeId); char connAddrStr[MAX_STRING_LENGTH]; memset(connAddrStr, 0, MAX_STRING_LENGTH); IO_ConvertIpAddressToString(connAddr, connAddrStr); sprintf(sdpRequestBuffer, "v=0\r\n" "o=user 8000 8000 IN IP4 %s\r\n" "s=SIP Call\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n" "m=audio %d RTP/AVP 0\r\n" "a=sendrecv\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=ptime:20\r\n", sip->SipGetFQDN(), connAddrStr, APP_RTP); unsigned int sdpRequestLength = (unsigned int)strlen(sdpRequestBuffer); sprintf(pBuffer, "INVITE %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %d INVITE\r\n" "Contact: <%s>\r\n" "Call-Info: %d\r\n" "Content-Type: application/sdp\r\n" "Content-Length: %d\r\n\r\n" "%s", // Add SDP msg body voip->destAliasAddr, protoBuf, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, voip->destAliasAddr, voip->sourceAliasAddr, tag, callId, sip->SipGenerateSeqCounter(), strcat(aliasAddr,myIPAddress), voip->callSignalPort, sdpRequestLength, // SDP msg body length sdpRequestBuffer);// SDP msg body str pLength = (unsigned int)strlen(pBuffer); // stats incremented sip->SipIncrementInviteSent(); sip->SipIncrementCallAttempted(); SipFillComponents(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s - \n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of forwarded sip - pBuffer: %d\n", pLength); } } // /** // FUNCTION :: SipCreate2xxAckRequestPkt // LAYER :: APPLICATION // PURPOSE :: create a sip Acknowledge request packet for 2xx response // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipCreate2xxAckRequestPkt(Node* node, SipData* sip) { char branch[MAX_STRING_LENGTH]; char protoBuf[SIP_STR_SIZE16]; if (sip->SipGetTransProtocolType() == TCP) { strcpy(protoBuf, "TCP"); } else if (sip->SipGetTransProtocolType() == UDP) { strcpy(protoBuf, "UDP"); } pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); sip->SipGenerateBranch(branch); sprintf(pBuffer, "ACK %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s ACK\r\n" "Content-Length: %d\r\n\r\n", to, protoBuf, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, to, tagTo, from, tagFrom, callId, cSeq, // Number must be same as the cseq# of invite being ACK 0); pLength = (unsigned int)strlen(pBuffer); sip->SipIncrementAckSent(); sip->SipIncrementCallConnected(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s - \n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of forwarded sip - pBuffer: %d\n", pLength); } }
static void add_ref_in_native_method(CRB_LocalEnvironment *env, CRB_Object *obj) { RefInNativeFunc *new_ref; new_ref = MEM_malloc(sizeof(RefInNativeFunc)); new_ref->object = obj; new_ref->next = env->ref_in_native_method; env->ref_in_native_method = new_ref; }
val_t SVM_MakeObject(SimpleVM *vm, int type) { SVMObject *ob = MEM_calloc(sizeof(*ob)); LinkNode *node = MEM_malloc(sizeof(*node)); ob->type = TYPE_OBJECT; node->value = ob; List_Append(&vm->objects, node); return SVM_Obj2Val(ob); }
static void svm_obj_ensuresize(SimpleVM *vm, SVMObject *ob, int size) { if (size >= ob->size) { int newsize = (size+1)*2; int *newnames = MEM_malloc(sizeof(*newnames)*newsize); val_t *newfields = MEM_malloc(sizeof(*newfields)*newsize); if (ob->fields) { memcpy(newfields, ob->fields, sizeof(*ob->fields)*ob->size); memcpy(newnames, ob->names, sizeof(*ob->names)*ob->size); MEM_free(ob->fields); MEM_free(ob->names); } ob->size = newsize; ob->names = newnames; ob->fields = newfields; } }
MVM_Object * mvm_create_array_double_i(MVM_VirtualMachine *mvm, int size) { MVM_Object *ret; ret = alloc_array(mvm, DOUBLE_ARRAY, size); ret->u.array.u.double_array = MEM_malloc(sizeof(double) * size); mvm->heap.current_heap_size += sizeof(double) * size; return ret; }
MVM_Object * mvm_create_array_int_i(MVM_VirtualMachine *mvm, int size) { MVM_Object *ret; ret = alloc_array(mvm, INT_ARRAY, size); ret->u.array.u.int_array = MEM_malloc(sizeof(int) * size); mvm->heap.current_heap_size += sizeof(int) * size; return ret; }
void raster_path_append(Raster *raster, Path *p, PathSegment *s) { if (!s) { fprintf(stderr, "error: NULL segment passed to render_path_append()\n"); return; } LinkNode *node = MEM_malloc(sizeof(*node)); node->data = s; list_append(&p->segments, node); }
static LocalEnviroment * alloc_local_enviroment() { LocalEnviroment *ret; ret = MEM_malloc(sizeof(LocalEnviroment)); ret->variable = NULL; ret->global_variable = NULL; return ret; }
CRB_Interpreter * CRB_create_interpreter(void) { MEM_Storage storage; CRB_Interpreter *interpreter; #ifndef MINICROWBAR extern void crb_compile_built_in_script(CRB_Interpreter *inter); #endif /* MINICROWBAR */ storage = MEM_open_storage(0); interpreter = MEM_storage_malloc(storage, sizeof(struct CRB_Interpreter_tag)); interpreter->interpreter_storage = storage; interpreter->execute_storage = MEM_open_storage(0); interpreter->variable = NULL; interpreter->function_list = NULL; interpreter->statement_list = NULL; interpreter->current_line_number = 1; interpreter->stack.stack_alloc_size = 0; interpreter->stack.stack_pointer = 0; interpreter->stack.stack = MEM_malloc(sizeof(CRB_Value) * STACK_ALLOC_SIZE); interpreter->heap.current_heap_size = 0; interpreter->heap.current_threshold = HEAP_THRESHOLD_SIZE; interpreter->heap.header = NULL; interpreter->top_environment = NULL; interpreter->current_exception.type = CRB_NULL_VALUE; interpreter->input_mode = CRB_FILE_INPUT_MODE; interpreter->regexp_literals = NULL; #ifdef EUC_SOURCE interpreter->source_encoding = EUC_ENCODING; #else #ifdef SHIFT_JIS_SOURCE interpreter->source_encoding = SHIFT_JIS_ENCODING; #else #ifdef UTF_8_SOURCE interpreter->source_encoding = UTF_8_ENCODING; #else DBG_panic(("source encoding is not defined.\n")); #endif #endif #endif crb_set_current_interpreter(interpreter); crb_add_native_functions(interpreter); crb_add_regexp_functions(interpreter); #ifndef MINICROWBAR crb_compile_built_in_script(interpreter); #endif /* MINICROWBAR */ return interpreter; }
// Copyright (c) 2001-2013, SCALABLE Network Technologies, Inc. All Rights Reserved. // 600 Corporate Pointe // Suite 1200 // Culver City, CA 90230 // [email protected] // // This source code is licensed, not sold, and is subject to a written // license agreement. Among other things, no portion of this source // code may be copied, transmitted, disclosed, displayed, distributed, // translated, used as the basis for a derivative work, or used, in // whole or in part, for any program or purpose other than its intended // use in compliance with the license agreement as part of the QualNet // software. This source code and certain of the algorithms contained // within it are confidential trade secrets of Scalable Network // Technologies, Inc. and may not be used as the basis for any other // software, hardware, product or service. // /** // PROTOCOL :: SIP // LAYER : APPLICATION // REFERENCES :: // + whatissip.pdf : www.sipcenter.com // + SIP-2003-Future_of_SIP_and_Presence.pdf // + siptutorial.pdf // COMMENTS :: This is implementation of SIP 2.0 as per RFC 3261 // **/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "api.h" #include "app_util.h" #include "multimedia_sipmsg.h" #include "multimedia_sipdata.h" #define DEBUG 0 // /** // FUNCTION :: SipMsg // LAYER :: APPLICATION // PURPOSE :: Constructor of the SipMsg class // PARAMETERS :: // RETURN :: NULL // **/ SipMsg :: SipMsg() { msgType = SIP_INVALID_MSG; requestType = INVALID_REQ; responseType = INVALID_RES; contentLength = 0; pBuffer = NULL; pLength = 0; totHdrLen = 0; maxForwards = SIP_MAX_FORWARDS; ackType = SIP_ACK_INVALID; connectionId = INVALID_ID; proxyConnectionId = INVALID_ID; fromIp = INVALID_ADDRESS; targetIp = INVALID_ADDRESS; memset(targetUrl , 0, sizeof(targetUrl)); via = NULL; maxViaCount = SIP_VIA_COUNT; viaCount = 0; next = NULL; memset(from, 0, sizeof(from)); memset(to, 0, sizeof(to)); memset(callId, 0, sizeof(callId)); memset(tagTo, 0, sizeof(tagTo)); memset(tagFrom, 0, sizeof(tagFrom)); memset(cSeq, 0, sizeof(cSeq)); memset(cSeqMsg, 0, sizeof(cSeqMsg)); memset(contact, 0, sizeof(contact)); memset(contentType, 0, sizeof(contentType)); memset(domainName, 0, sizeof(domainName)); memset(transProto, 0, sizeof(transProto)); memset(callInfo, 0, sizeof(callInfo)); } // /** // FUNCTION :: SipMsg // LAYER :: APPLICATION // PURPOSE :: Destructor of the SipMsg class // PARAMETERS :: // RETURN :: NULL // **/ SipMsg :: ~SipMsg() { if (via != NULL) { MEM_free(via); } via = NULL; } // /** // FUNCTION :: SipGenerateVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +viaGen : char* : Field to be filled up // +start : int : starting address // +isBye : bool : true for a BYE message // RETURN :: void : NULL // **/ void SipMsg :: SipGenerateVia(char* viaGen, int start, bool isBye) { // count refers to no of vias int count = start; int storedCount = 0; int offset = 0; while (count < viaCount) { if (via[count].isReceivedIp && !isBye) { storedCount = sprintf(viaGen + offset, "Via: SIP/2.0/%s %s;branch=%s;received=%s\r\n", transProto, via[count].viaProxy, via[count].branch, via[count].receivedIp); offset += storedCount; } else { storedCount = sprintf(viaGen + offset, "Via: SIP/2.0/%s %s;branch=%s\r\n", transProto, via[count].viaProxy, via[count].branch); offset += storedCount; } count++; } } // /** // FUNCTION :: SipGenViaWithOwnVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +localVia : char* : Field to be filled up // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipGenViaWithOwnVia(char* localVia, SipData* sip) { char branch[SIP_STR_SIZE16]; char via[SIP_VIA_COUNT * MAX_STRING_LENGTH]; ERROR_Assert(localVia, "Via field cannot be NULL\n"); sip->SipGenerateBranch(branch); sprintf(via, "Via: SIP/2.0/%s %s;branch=%s\r\n", transProto, sip->SipGetFQDN(), branch); SipGenerateVia(via + strlen(via)); memcpy(localVia, via, strlen(via)); } // /** // FUNCTION :: SipGenViaWithoutTopVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +localVia : char* : Field to be filled up // RETURN :: void : NULL // **/ void SipMsg :: SipGenViaWithoutTopVia(char* localVia) { // routine assumes via parsing is already done and // therefore viaCount contains the numb of vias present ERROR_Assert(localVia, "localVia field cannot be NULL\n"); SipGenerateVia(localVia, 1); } // /** // FUNCTION :: SipUpdateViaWithReceivedIp // LAYER :: APPLICATION // PURPOSE :: Update via field with the received Ip // PARAMETERS :: // RETURN :: void : NULL // **/ void SipMsg :: SipUpdateViaWithReceivedIp() { char recdIpStr[SIP_STR_SIZE16]; if (viaCount < 1) { // no via available return; } IO_ConvertIpAddressToString(fromIp, recdIpStr); strcpy(via[0].receivedIp, recdIpStr); via[0].isReceivedIp = true; } // /** // FUNCTION :: SipGetResponseString // LAYER :: APPLICATION // PURPOSE :: Get the respone string corresponding to an enum // PARAMETERS :: // +responseType : SipResType : Response type // +responseStr : char* : string to be filled up // RETURN :: void : NULL // **/ void SipMsg :: SipGetResponseString(SipResType responseType, char* responseStr) { switch (responseType) { case TRYING: strcpy(responseStr, "Trying"); break; case RINGING: strcpy(responseStr, "Ringing"); break; case OK: strcpy(responseStr, "OK"); break; default: strcpy(responseStr, ""); } } // /** // FUNCTION :: SipCreateInviteRequestPkt // LAYER :: APPLICATION // PURPOSE :: Create Sip Invite request packet // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // +voip : VoipHostData*: Pointer to VoipHostData // RETURN :: void : NULL // **/ void SipMsg :: SipCreateInviteRequestPkt(Node* node, SipData* sip, VoipHostData* voip) { char protoBuf[SIP_STR_SIZE16]; char branch[MAX_STRING_LENGTH]; char callId[SIP_STR_SIZE64]; char tag[SIP_STR_SIZE16]; char myIPAddress[MAX_STRING_LENGTH]; char aliasAddr[MAX_ALIAS_ADDR_SIZE]; Address addr; Int32 i = -1; if (sip->SipGetTransProtocolType() == TCP) { strcpy(protoBuf, "TCP"); } else if (sip->SipGetTransProtocolType() == UDP) { strcpy(protoBuf, "UDP"); } pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); do { i++; aliasAddr[i] = voip->sourceAliasAddr[i]; }while (voip->sourceAliasAddr[i] != '@'); aliasAddr[++i] = '\0'; addr.networkType = NETWORK_IPV4; addr.interfaceAddr.ipv4 = voip->localAddr; IO_ConvertIpAddressToString(&addr , myIPAddress); sip->SipGenerateBranch(branch); sip->SipGenerateTag(node, tag); sip->SipGenerateCallIdPfx(node, callId); // Add a sample SDP for audio in SIP request msg body // Note: 1. include only the required items, and must be in order; // 2. most are hardcoded for simplicity---just as placeholders in simulation and not parsed; // 3. use fixed RTP port for simplicity---same src/dst port for RTP, so as to let wireshark recognize RTP by port char sdpRequestBuffer[BIG_STRING_LENGTH]; // buffer size 512, enough for the following SIP msg body: 116+4(port#)+FQDN memset(sdpRequestBuffer, 0, BIG_STRING_LENGTH); // This works for node with single interface---should use the sending interface IP if multiple NodeAddress connAddr = MAPPING_GetDefaultInterfaceAddressFromNodeId(node, node->nodeId); char connAddrStr[MAX_STRING_LENGTH]; memset(connAddrStr, 0, MAX_STRING_LENGTH); IO_ConvertIpAddressToString(connAddr, connAddrStr); sprintf(sdpRequestBuffer, "v=0\r\n" "o=user 8000 8000 IN IP4 %s\r\n" "s=SIP Call\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n" "m=audio %d RTP/AVP 0\r\n" "a=sendrecv\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=ptime:20\r\n", sip->SipGetFQDN(), connAddrStr, APP_RTP); unsigned int sdpRequestLength = (unsigned int)strlen(sdpRequestBuffer); sprintf(pBuffer, "INVITE %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %d INVITE\r\n" "Contact: <%s>\r\n" "Call-Info: %d\r\n" "Content-Type: application/sdp\r\n" "Content-Length: %d\r\n\r\n" "%s", // Add SDP msg body voip->destAliasAddr, protoBuf, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, voip->destAliasAddr, voip->sourceAliasAddr, tag, callId, sip->SipGenerateSeqCounter(), strcat(aliasAddr,myIPAddress), voip->callSignalPort, sdpRequestLength, // SDP msg body length sdpRequestBuffer);// SDP msg body str pLength = (unsigned int)strlen(pBuffer); // stats incremented sip->SipIncrementInviteSent(); sip->SipIncrementCallAttempted(); SipFillComponents(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s - \n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of forwarded sip - pBuffer: %d\n", pLength); } } // /** // FUNCTION :: SipCreate2xxAckRequestPkt // LAYER :: APPLICATION // PURPOSE :: create a sip Acknowledge request packet for 2xx response // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipCreate2xxAckRequestPkt(Node* node, SipData* sip) { char branch[MAX_STRING_LENGTH]; char protoBuf[SIP_STR_SIZE16]; if (sip->SipGetTransProtocolType() == TCP) { strcpy(protoBuf, "TCP"); } else if (sip->SipGetTransProtocolType() == UDP) { strcpy(protoBuf, "UDP"); } pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); sip->SipGenerateBranch(branch); sprintf(pBuffer, "ACK %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s ACK\r\n" "Content-Length: %d\r\n\r\n", to, protoBuf, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, to, tagTo, from, tagFrom, callId, cSeq, // Number must be same as the cseq# of invite being ACK 0); pLength = (unsigned int)strlen(pBuffer); sip->SipIncrementAckSent(); sip->SipIncrementCallConnected(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s - \n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of forwarded sip - pBuffer: %d\n", pLength); } } // /** // FUNCTION :: SipCreateNon2xxAckRequestPkt // LAYER :: APPLICATION // PURPOSE :: create a sip Acknowledge request packet for Non2xx response // (This ack is sent for final responses between 300 and 699) // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipCreateNon2xxAckRequestPkt(Node* node, SipData* sip) { char branch[MAX_STRING_LENGTH]; char protoBuf[SIP_STR_SIZE16]; if (sip->SipGetTransProtocolType() == TCP) { strcpy(protoBuf, "TCP"); } else if (sip->SipGetTransProtocolType() == UDP) { strcpy(protoBuf, "UDP"); } // Note: This ack must contain a single via Header,i.e.top level via. // Ref: SEC 17.1.1.3 pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); sip->SipGenerateBranch(branch); sprintf(pBuffer, "ACK %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s ACK\r\n\r\n", to, protoBuf, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, to, tagTo, from, tagFrom, callId, cSeq); pLength = (unsigned int)strlen(pBuffer); sip->SipIncrementAckSent(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s -\n%s\n", node->nodeId, clockStr, msgBuf); } }
DBG_Controller DBG_create_controller_func(void) { DBG_Controller controller; controller = MEM_malloc(sizeof(struct DBG_Controller_tag)); controller->debug_write_fp = NULL; controller->current_debug_level = INT_MAX; return controller; }
//------------------------------------------------------------------------- // FUNCTION : NdpInitNeighborCahce() // // PURPOSE : initializing a neighbor cache // // PARAMETERS : neighborCache - pointer to neighbor cache // // RETURN VALUE : None //------------------------------------------------------------------------- static void NdpInitNeighborCahce(NdpNeighborTable* neighborCache) { neighborCache->neighborTable = (NdpNeighborStruct*) MEM_malloc(sizeof(NdpNeighborStruct) * NDP_INITIAL_CACHE_ENTRY); memset(neighborCache->neighborTable, 0, (sizeof(NdpNeighborStruct) * NDP_INITIAL_CACHE_ENTRY)); neighborCache->numEntry = 0; neighborCache->maxEntry = NDP_INITIAL_CACHE_ENTRY; }
// Copyright (c) 2001-2013, SCALABLE Network Technologies, Inc. All Rights Reserved. // 600 Corporate Pointe // Suite 1200 // Culver City, CA 90230 // [email protected] // // This source code is licensed, not sold, and is subject to a written // license agreement. Among other things, no portion of this source // code may be copied, transmitted, disclosed, displayed, distributed, // translated, used as the basis for a derivative work, or used, in // whole or in part, for any program or purpose other than its intended // use in compliance with the license agreement as part of the QualNet // software. This source code and certain of the algorithms contained // within it are confidential trade secrets of Scalable Network // Technologies, Inc. and may not be used as the basis for any other // software, hardware, product or service. // /** // PROTOCOL :: SIP // LAYER : APPLICATION // REFERENCES :: // + whatissip.pdf : www.sipcenter.com // + SIP-2003-Future_of_SIP_and_Presence.pdf // + siptutorial.pdf // COMMENTS :: This is implementation of SIP 2.0 as per RFC 3261 // **/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "api.h" #include "app_util.h" #include "multimedia_sipmsg.h" #include "multimedia_sipdata.h" #define DEBUG 0 // /** // FUNCTION :: SipMsg // LAYER :: APPLICATION // PURPOSE :: Constructor of the SipMsg class // PARAMETERS :: // RETURN :: NULL // **/ SipMsg :: SipMsg() { msgType = SIP_INVALID_MSG; requestType = INVALID_REQ; responseType = INVALID_RES; contentLength = 0; pBuffer = NULL; pLength = 0; totHdrLen = 0; maxForwards = SIP_MAX_FORWARDS; ackType = SIP_ACK_INVALID; connectionId = INVALID_ID; proxyConnectionId = INVALID_ID; fromIp = INVALID_ADDRESS; targetIp = INVALID_ADDRESS; memset(targetUrl , 0, sizeof(targetUrl)); via = NULL; maxViaCount = SIP_VIA_COUNT; viaCount = 0; next = NULL; memset(from, 0, sizeof(from)); memset(to, 0, sizeof(to)); memset(callId, 0, sizeof(callId)); memset(tagTo, 0, sizeof(tagTo)); memset(tagFrom, 0, sizeof(tagFrom)); memset(cSeq, 0, sizeof(cSeq)); memset(cSeqMsg, 0, sizeof(cSeqMsg)); memset(contact, 0, sizeof(contact)); memset(contentType, 0, sizeof(contentType)); memset(domainName, 0, sizeof(domainName)); memset(transProto, 0, sizeof(transProto)); memset(callInfo, 0, sizeof(callInfo)); } // /** // FUNCTION :: SipMsg // LAYER :: APPLICATION // PURPOSE :: Destructor of the SipMsg class // PARAMETERS :: // RETURN :: NULL // **/ SipMsg :: ~SipMsg() { if (via != NULL) { MEM_free(via); } via = NULL; } // /** // FUNCTION :: SipGenerateVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +viaGen : char* : Field to be filled up // +start : int : starting address // +isBye : bool : true for a BYE message // RETURN :: void : NULL // **/ void SipMsg :: SipGenerateVia(char* viaGen, int start, bool isBye) { // count refers to no of vias int count = start; int storedCount = 0; int offset = 0; while (count < viaCount) { if (via[count].isReceivedIp && !isBye) { storedCount = sprintf(viaGen + offset, "Via: SIP/2.0/%s %s;branch=%s;received=%s\r\n", transProto, via[count].viaProxy, via[count].branch, via[count].receivedIp); offset += storedCount; } else { storedCount = sprintf(viaGen + offset, "Via: SIP/2.0/%s %s;branch=%s\r\n", transProto, via[count].viaProxy, via[count].branch); offset += storedCount; } count++; } } // /** // FUNCTION :: SipGenViaWithOwnVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +localVia : char* : Field to be filled up // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipGenViaWithOwnVia(char* localVia, SipData* sip) { char branch[SIP_STR_SIZE16]; char via[SIP_VIA_COUNT * MAX_STRING_LENGTH]; ERROR_Assert(localVia, "Via field cannot be NULL\n"); sip->SipGenerateBranch(branch); sprintf(via, "Via: SIP/2.0/%s %s;branch=%s\r\n", transProto, sip->SipGetFQDN(), branch); SipGenerateVia(via + strlen(via)); memcpy(localVia, via, strlen(via)); } // /** // FUNCTION :: SipGenViaWithoutTopVia // LAYER :: APPLICATION // PURPOSE :: Generate the Via field // PARAMETERS :: // +localVia : char* : Field to be filled up // RETURN :: void : NULL // **/ void SipMsg :: SipGenViaWithoutTopVia(char* localVia) { // routine assumes via parsing is already done and // therefore viaCount contains the numb of vias present ERROR_Assert(localVia, "localVia field cannot be NULL\n"); SipGenerateVia(localVia, 1); } // /** // FUNCTION :: SipUpdateViaWithReceivedIp // LAYER :: APPLICATION // PURPOSE :: Update via field with the received Ip // PARAMETERS :: // RETURN :: void : NULL // **/ void SipMsg :: SipUpdateViaWithReceivedIp() { char recdIpStr[SIP_STR_SIZE16]; if (viaCount < 1) { // no via available return; } IO_ConvertIpAddressToString(fromIp, recdIpStr); strcpy(via[0].receivedIp, recdIpStr); via[0].isReceivedIp = true; } // /** // FUNCTION :: SipGetResponseString // LAYER :: APPLICATION // PURPOSE :: Get the respone string corresponding to an enum // PARAMETERS :: // +responseType : SipResType : Response type // +responseStr : char* : string to be filled up // RETURN :: void : NULL // **/ void SipMsg :: SipGetResponseString(SipResType responseType, char* responseStr) { switch (responseType) { case TRYING: strcpy(responseStr, "Trying"); break; case RINGING: strcpy(responseStr, "Ringing"); break; case OK: strcpy(responseStr, "OK"); break; default: strcpy(responseStr, ""); } } // /** // FUNCTION :: SipCreateInviteRequestPkt // LAYER :: APPLICATION // PURPOSE :: Create Sip Invite request packet // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // +voip : VoipHostData*: Pointer to VoipHostData // RETURN :: void : NULL // **/ void SipMsg :: SipCreateInviteRequestPkt(Node* node, SipData* sip, VoipHostData* voip) { char protoBuf[SIP_STR_SIZE16]; char branch[MAX_STRING_LENGTH]; char callId[SIP_STR_SIZE64]; char tag[SIP_STR_SIZE16]; char myIPAddress[MAX_STRING_LENGTH]; char aliasAddr[MAX_ALIAS_ADDR_SIZE]; Address addr; Int32 i = -1; if (sip->SipGetTransProtocolType() == TCP) { strcpy(protoBuf, "TCP"); } else if (sip->SipGetTransProtocolType() == UDP) { strcpy(protoBuf, "UDP"); } pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); do { i++; aliasAddr[i] = voip->sourceAliasAddr[i]; }while (voip->sourceAliasAddr[i] != '@'); aliasAddr[++i] = '\0'; addr.networkType = NETWORK_IPV4; addr.interfaceAddr.ipv4 = voip->localAddr; IO_ConvertIpAddressToString(&addr , myIPAddress); sip->SipGenerateBranch(branch); sip->SipGenerateTag(node, tag); sip->SipGenerateCallIdPfx(node, callId); // Add a sample SDP for audio in SIP request msg body // Note: 1. include only the required items, and must be in order; // 2. most are hardcoded for simplicity---just as placeholders in simulation and not parsed; // 3. use fixed RTP port for simplicity---same src/dst port for RTP, so as to let wireshark recognize RTP by port char sdpRequestBuffer[BIG_STRING_LENGTH]; // buffer size 512, enough for the following SIP msg body: 116+4(port#)+FQDN memset(sdpRequestBuffer, 0, BIG_STRING_LENGTH); // This works for node with single interface---should use the sending interface IP if multiple NodeAddress connAddr = MAPPING_GetDefaultInterfaceAddressFromNodeId(node, node->nodeId); char connAddrStr[MAX_STRING_LENGTH]; memset(connAddrStr, 0, MAX_STRING_LENGTH); IO_ConvertIpAddressToString(connAddr, connAddrStr); sprintf(sdpRequestBuffer, "v=0\r\n" "o=user 8000 8000 IN IP4 %s\r\n" "s=SIP Call\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n" "m=audio %d RTP/AVP 0\r\n" "a=sendrecv\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=ptime:20\r\n", sip->SipGetFQDN(), connAddrStr, APP_RTP); unsigned int sdpRequestLength = (unsigned int)strlen(sdpRequestBuffer); sprintf(pBuffer, "INVITE %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %d INVITE\r\n" "Contact: <%s>\r\n" "Call-Info: %d\r\n" "Content-Type: application/sdp\r\n" "Content-Length: %d\r\n\r\n" "%s", // Add SDP msg body voip->destAliasAddr, protoBuf, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, voip->destAliasAddr, voip->sourceAliasAddr, tag, callId, sip->SipGenerateSeqCounter(), strcat(aliasAddr,myIPAddress), voip->callSignalPort, sdpRequestLength, // SDP msg body length sdpRequestBuffer);// SDP msg body str pLength = (unsigned int)strlen(pBuffer); // stats incremented sip->SipIncrementInviteSent(); sip->SipIncrementCallAttempted(); SipFillComponents(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s - \n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of forwarded sip - pBuffer: %d\n", pLength); } } // /** // FUNCTION :: SipCreate2xxAckRequestPkt // LAYER :: APPLICATION // PURPOSE :: create a sip Acknowledge request packet for 2xx response // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipCreate2xxAckRequestPkt(Node* node, SipData* sip) { char branch[MAX_STRING_LENGTH]; char protoBuf[SIP_STR_SIZE16]; if (sip->SipGetTransProtocolType() == TCP) { strcpy(protoBuf, "TCP"); } else if (sip->SipGetTransProtocolType() == UDP) { strcpy(protoBuf, "UDP"); } pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); sip->SipGenerateBranch(branch); sprintf(pBuffer, "ACK %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s ACK\r\n" "Content-Length: %d\r\n\r\n", to, protoBuf, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, to, tagTo, from, tagFrom, callId, cSeq, // Number must be same as the cseq# of invite being ACK 0); pLength = (unsigned int)strlen(pBuffer); sip->SipIncrementAckSent(); sip->SipIncrementCallConnected(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s - \n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of forwarded sip - pBuffer: %d\n", pLength); } } // /** // FUNCTION :: SipCreateNon2xxAckRequestPkt // LAYER :: APPLICATION // PURPOSE :: create a sip Acknowledge request packet for Non2xx response // (This ack is sent for final responses between 300 and 699) // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipCreateNon2xxAckRequestPkt(Node* node, SipData* sip) { char branch[MAX_STRING_LENGTH]; char protoBuf[SIP_STR_SIZE16]; if (sip->SipGetTransProtocolType() == TCP) { strcpy(protoBuf, "TCP"); } else if (sip->SipGetTransProtocolType() == UDP) { strcpy(protoBuf, "UDP"); } // Note: This ack must contain a single via Header,i.e.top level via. // Ref: SEC 17.1.1.3 pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); sip->SipGenerateBranch(branch); sprintf(pBuffer, "ACK %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s ACK\r\n\r\n", to, protoBuf, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, to, tagTo, from, tagFrom, callId, cSeq); pLength = (unsigned int)strlen(pBuffer); sip->SipIncrementAckSent(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s -\n%s\n", node->nodeId, clockStr, msgBuf); } } // /** // FUNCTION :: SipCreateByeRequestPkt // LAYER :: APPLICATION // PURPOSE :: Create a Bye request packet // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // RETURN :: void : NULL // **/ void SipMsg :: SipCreateByeRequestPkt(Node* node, SipData* sip, SipTransactionState state) { char branch[MAX_STRING_LENGTH]; sip->SipGenerateBranch(branch); pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); // Note that sender of BYE request creates a new transaction // within the scope of current dialogue. So it genereates and // uses a new CSeq number and if it is the same node that has // issued the Invite request then from and to field values remain // unaltered else if the called node hangs up first then it // is the node that issues the BYE request and hence from and to // field aliases including tags are swapped for creation of this req. // Call Id remains the same as it is the same dlg. if (state == SIP_CLIENT) { sprintf(pBuffer, "BYE %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %d BYE\r\n" "Content-Length: %d\r\n\r\n", to, transProto, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, to, tagTo, from, tagFrom, callId, sip->SipGenerateSeqCounter(), 0); } else if (state == SIP_SERVER) { // must swap from and to fields sprintf(pBuffer, "BYE %s SIP/2.0\r\n" "Via: SIP/2.0/%s %s;branch=%s\r\n" "Max-Forwards: %d\r\n" "To: <%s>;tag=%s\r\n" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %d BYE\r\n" "Content-Length: %d\r\n\r\n", from, transProto, sip->SipGetFQDN(), branch, SIP_MAX_FORWARDS, from, tagFrom, to, tagTo, callId, sip->SipGenerateSeqCounter(), 0); } pLength = (unsigned int)strlen(pBuffer); sip->SipIncrementByeSent(); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s -\n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of sip - pBuffer being sent: %d\n", pLength); } } // /** // FUNCTION :: SipCreateResponsePkt // LAYER :: APPLICATION // PURPOSE :: Create a response packet // PARAMETERS :: // +node : Node* : Pointer to the node // +sip : SipData* : Pointer to SipData // +responseType: SipResType : Sip response type // +requestType : char* : request type // RETURN :: void : NULL // **/ void SipMsg :: SipCreateResponsePkt(Node* node, SipData* sip, SipResType responseType, const char* requestType) { char via[SIP_VIA_COUNT * SIP_STR_SIZE64]; char responseStr[SIP_STR_SIZE16]; char toBuf[SIP_STR_SIZE64]; pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); memset(via, 0, SIP_VIA_COUNT * SIP_STR_SIZE64); SipGetResponseString(responseType, responseStr); if (sip->SipGetCallModel() == SipProxyRouted) { SipUpdateViaWithReceivedIp(); } switch (responseType) { case RINGING: { SipGenerateVia(via); sip->SipGenerateTag(node, tagTo); sprintf(toBuf, "To: <%s>;tag=%s\r\n", to, tagTo); break; } case OK: { if (!strcmp(requestType, "BYE")) { SipGenerateVia(via, 0, true); } else { SipGenerateVia(via); } sprintf(toBuf, "To: <%s>;tag=%s\r\n", to, tagTo); break; } case TRYING: { SipGenerateVia(via); sprintf(toBuf, "To: <%s>\r\n", to); break; } default: break; } // add msg body for 200 OK response to INVITE if (responseType == OK && !strcmp(requestType, "INVITE")) { char sdpResponseBuffer[BIG_STRING_LENGTH]; // buffer size 512, enough for the following SIP msg body: 127+4(port#)+FQDN+IP memset(sdpResponseBuffer, 0, BIG_STRING_LENGTH); // This works for node with single interface---should use the sending interface IP if multiple NodeAddress connAddr = MAPPING_GetDefaultInterfaceAddressFromNodeId(node, node->nodeId); char connAddrStr[MAX_STRING_LENGTH]; memset(connAddrStr, 0, MAX_STRING_LENGTH); IO_ConvertIpAddressToString(connAddr, connAddrStr); sprintf(sdpResponseBuffer, "v=0\r\n" "o=user 8000 8000 IN IP4 %s\r\n" "s=SIP Call\r\n" "c=IN IP4 %s\r\n" "t=0 0\r\n" "m=audio %d RTP/AVP 0\r\n" "a=sendrecv\r\n" "a=rtpmap:0 PCMU/8000\r\n" "a=ptime:20\r\n", sip->SipGetFQDN(), connAddrStr, // own IP address APP_RTP); unsigned int sdpResponseLength = (unsigned int)strlen(sdpResponseBuffer); sprintf(pBuffer, "SIP/2.0 %d %s\r\n" "%s" "%s" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s %s\r\n" "Content-Type: application/sdp\r\n" "Content-Length: %d\r\n\r\n" "%s", responseType, responseStr, via, toBuf, from, tagFrom, callId, cSeq, requestType, sdpResponseLength, sdpResponseBuffer); } else { sprintf(pBuffer, "SIP/2.0 %d %s\r\n" "%s" "%s" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "CSeq: %s %s\r\n" "Content-Length: %d\r\n\r\n", responseType, responseStr, via, toBuf, from, tagFrom, callId, cSeq, requestType, 0); } pLength = (unsigned int)strlen(pBuffer); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s -\n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of sip - pBuffer being sent: %d\n", pLength); } } //--------------------------------------------------------------------------- // FUNCTION: SipCreate2xxOkResponsePkt() // PURPOSE: Create a 200 OK response packet // PARAMETERS: node::Pointer to the node // sip::Pointer to SipData // voip::Pointer to VoipHostData // RETURN: None. //--------------------------------------------------------------------------- void SipMsg :: SipCreate2xxOkResponsePkt(Node* node, SipData* sip, VoipHostData* voip) { char via[SIP_VIA_COUNT * SIP_STR_SIZE64]; char responseStr[SIP_STR_SIZE16]; char toBuf[SIP_STR_SIZE64]; SipResType responseType = OK; const char* requestType = "INVITE"; char myIPAddress[MAX_STRING_LENGTH]; char aliasAddr[MAX_ALIAS_ADDR_SIZE]; SipGetResponseString(responseType, responseStr); Address addr; Int32 i = -1; pBuffer = (char*) MEM_malloc(MAX_SIP_PACKET_SIZE); memset(pBuffer, 0, MAX_SIP_PACKET_SIZE); memset(via, 0, SIP_VIA_COUNT * SIP_STR_SIZE64); if (sip->SipGetCallModel() == SipProxyRouted) { SipUpdateViaWithReceivedIp(); } do { i++; aliasAddr[i] = voip->sourceAliasAddr[i]; }while (voip->sourceAliasAddr[i] != '@'); aliasAddr[++i] = '\0'; addr.networkType = NETWORK_IPV4; //taking the fresh IP Address voip->localAddr = MAPPING_GetInterfaceAddrForNodeIdAndIntfId( node, node->nodeId, voip->clientInterfaceIndex); addr.interfaceAddr.ipv4 = voip->localAddr; IO_ConvertIpAddressToString(&addr , myIPAddress); //OK Response SipGenerateVia(via); sprintf(toBuf, "To: <%s>;tag=%s\r\n", to, tagTo); sprintf(pBuffer, "SIP/2.0 %d %s\r\n" "%s" "%s" "From: <%s>;tag=%s\r\n" "Call-ID: %s\r\n" "Contact: <%s>\r\n" "CSeq: %s %s\r\n" "Content-Length: %d\r\n\r\n", responseType, responseStr, via, toBuf, from, tagFrom, callId, strcat(aliasAddr , myIPAddress), cSeq, requestType, 0); pLength = (unsigned int)strlen(pBuffer); if (DEBUG) { char clockStr[MAX_STRING_LENGTH]; TIME_PrintClockInSecond(node->getNodeTime(), clockStr); char msgBuf[MAX_SIP_PACKET_SIZE] = {0}; memcpy(msgBuf, pBuffer, pLength); printf("Node: %u sends following message at: %s -\n%s\n", node->nodeId, clockStr, msgBuf); printf("Length of sip - pBuffer being sent: %d\n", pLength); } } // /** // FUNCTION :: SipIsRequestMsg // LAYER :: APPLICATION // PURPOSE :: Check the type of received sip message // PARAMETERS :: // +token1 : char* : Input buffer // RETURN :: SipMsgType : Type of Sip message // **/ SipMsgType SipMsg :: SipIsRequestMsg(char* token1) { if (!strcmp(token1, "INVITE")) { requestType = INV; } else if (!strcmp(token1, "ACK")) { requestType = ACK; } else if (!strcmp(token1, "BYE")) { requestType = BYE; } else if (!strcmp(token1, "OPTIONS")) { requestType = OPT; } else if (!strcmp(token1, "REGISTER")) { requestType = REG; } else if (!strcmp(token1, "CANCEL")) { requestType = CAN; } else { requestType = INVALID_REQ; } if (requestType == INVALID_REQ) { msgType = SIP_INVALID_MSG; } else { msgType = SIP_REQUEST; } return msgType; } // /** // FUNCTION :: SipIsResponseMsg // LAYER :: APPLICATION // PURPOSE :: Check the type of received sip message // PARAMETERS :: // +responseToken : char* : Input buffer // +resString : char* : response string // RETURN :: SipMsgType : Type of Sip message // **/ SipMsgType SipMsg :: SipIsResponseMsg(char* responseToken, char* resString) { switch (atoi(responseToken)) { case TRYING: if (strcmp(resString, "Trying")) { return SIP_INVALID_MSG; } responseType = TRYING; break; case RINGING: if (strcmp(resString, "Ringing")) { return SIP_INVALID_MSG; } responseType = RINGING; break; case OK: if (strcmp(resString, "OK")) { return SIP_INVALID_MSG; } responseType = OK; break; default: responseType = INVALID_RES; break; } if (responseType == INVALID_RES) { msgType = SIP_INVALID_MSG; } else { msgType = SIP_RESPONSE; } return msgType; } // /** // FUNCTION :: SipParseTo // LAYER :: APPLICATION // PURPOSE :: Parse the input field // PARAMETERS :: // +toField : char* : Field to be parsed // RETURN :: void : NULL // **/ void SipMsg :: SipParseTo(char* toField) { char* next; const char* delims = {" ;"}; char* token; char field1[SIP_STR_SIZE16]; char field2[SIP_STR_SIZE64]; //Incresed Array size to 32 to fix memory corruption. char field3[SIP_STR_SIZE32]; memset(field1, 0, sizeof(field1)); memset(field2, 0, sizeof(field2)); memset(field3, 0, sizeof(field3)); IO_GetDelimitedToken(field1, toField, delims, &next); IO_GetDelimitedToken(field2, next, delims, &next); token = IO_GetDelimitedToken(field3, next, delims, &next); // strip off < and > memcpy(to, field2 + 1, strlen(field2) - 2); if (token) { sscanf(field3, "tag=%s", tagTo); } } // /** // FUNCTION :: SipParseVia // LAYER :: APPLICATION // PURPOSE :: Parse the input field // PARAMETERS :: // +currVia : char* : Field to be parsed // RETURN :: void : NULL // **/ void SipMsg :: SipParseVia(char* currVia) { char token1[SIP_STR_SIZE64]; const char* delims = ";= \r\n"; char* next; if (viaCount >= maxViaCount) { maxViaCount += SIP_VIA_COUNT; SipVia* newVia = (SipVia*) MEM_malloc(sizeof(SipVia) * maxViaCount); memcpy(newVia, via, sizeof(SipVia) * viaCount); MEM_free(via); via = newVia; } // ignore version IO_GetDelimitedToken(token1, currVia, delims, &next); IO_GetDelimitedToken(token1, next, delims, &next); strcpy(transProto, token1 + strlen(token1) - 3); // get domain name IO_GetDelimitedToken(token1, next, delims, &next); strcpy(via[viaCount].viaProxy, token1); // get branch keyword IO_GetDelimitedToken(token1, next, delims, &next); if (!strcmp(token1, "branch")) { // get branch value IO_GetDelimitedToken(token1, next, delims, &next); strcpy(via[viaCount].branch, token1); } // get received keyword if any IO_GetDelimitedToken(token1, next, delims, &next); if (!strcmp(token1, "received")) { // get received value IO_GetDelimitedToken(token1, next, delims, &next); via[viaCount].isReceivedIp = true; strcpy(via[viaCount].receivedIp, token1); IO_GetDelimitedToken(token1, next, delims, &next); } else { via[viaCount].isReceivedIp = false; } viaCount++; } // /** // FUNCTION :: SipAllocateVia // LAYER :: APPLICATION // PURPOSE :: Init and allocate memory for the Via field // PARAMETERS :: // RETURN :: void : NULL // **/ void SipMsg :: SipAllocateVia() { if (via) { viaCount = 0; MEM_free(via); via = NULL; } via = (SipVia*) MEM_malloc(sizeof(SipVia) * SIP_VIA_COUNT); memset(via, 0, sizeof(SipVia) * SIP_VIA_COUNT); }
void STAT_AggregatedAverage::Serialize( clocktype now, char** data, int* size) { *data = (char*) MEM_malloc(sizeof(STAT_AggregationData)); *size = sizeof(STAT_AggregationData); STAT_AggregationData* agg = (STAT_AggregationData*) *data; agg->m_Value = m_Value; agg->m_Value2 = m_NumStatistics; agg->m_NumDataPoints = m_NumDataPoints; }
void STAT_AggregatedThroughput::Serialize( clocktype now, char** data, int* size) { *data = (char*) MEM_malloc(sizeof(STAT_AggregationData)); *size = sizeof(STAT_AggregationData); STAT_AggregationData* agg = (STAT_AggregationData*) *data; agg->m_Value = m_BytesProcessed; agg->m_NumDataPoints = m_NumDataPoints; }
Variable * crb_add_local_variable(CRB_LocalEnvironment *env, char *identifier) { Variable *new_variable; new_variable = MEM_malloc(sizeof(Variable)); new_variable->name = identifier; new_variable->next = env->variable; env->variable = new_variable; return new_variable; }
static BrpQueryCoverageEntry* BrpAddNewQueryCoverageEntry(BrpData* brpData) { BrpQueryCoverageTable* coverageTable = &brpData->queryCoverageTable; BrpQueryCoverageEntry* coverageEntry = coverageTable->coverageEntry; BrpQueryCoverageEntry* prevEntry = coverageEntry; if (coverageTable->numEntry == 0) { // This is the first entry in the list coverageTable->coverageEntry = (BrpQueryCoverageEntry*) MEM_malloc(sizeof(BrpQueryCoverageEntry)); coverageEntry = coverageTable->coverageEntry; } else { // Already there are some entry in the query // coverage table. Go to the last entry and add a // new entry there. while (coverageEntry != NULL) { prevEntry = coverageEntry; coverageEntry = coverageEntry->next; } ERROR_Assert(prevEntry != NULL, "Strange!!"); prevEntry->next = (BrpQueryCoverageEntry*) MEM_malloc(sizeof(BrpQueryCoverageEntry)); coverageEntry = prevEntry->next; } coverageTable->numEntry++; return coverageEntry; }