NwGtpv1uRcT nwMiniUlpDestroyConn(NwMiniUlpEntityT* thiz) { NwGtpv1uRcT rc; NwGtpv1uUlpApiT ulpReq; /*--------------------------------------------------------------------------- * Send Destroy Session Request to GTPv1u Stack Instance *--------------------------------------------------------------------------*/ ulpReq.apiType = NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT; ulpReq.apiInfo.destroyTunnelEndPointInfo.hStackSessionHandle = thiz->hGtpv1uConn; rc = nwGtpv1uProcessUlpReq(thiz->hGtpv1uStack, &ulpReq); NW_ASSERT( rc == NW_GTPV1U_OK ); thiz->hGtpv1uConn = 0; return NW_GTPV1U_OK; }
NwSdpRcT nwSdpProcessGtpuDataInd( NW_IN NwSdpHandleT hSdp, NW_IN NwU8T* udpData, NW_IN NwU32T udpDataLen, NW_IN NwU16T peerPort, NW_IN NwU32T peerIp) { NwSdpRcT rc; NwSdpT* thiz; NwU16T msgType; thiz = (NwSdpT*) hSdp; NW_ASSERT(thiz); NW_ENTER(thiz); rc = nwGtpv1uProcessUdpReq(thiz->hGtpv1uStack, udpData, udpDataLen, peerPort, peerIp); NW_LEAVE(thiz); return rc; }
static NW_Status_t Attr_Start_CB (NW_WBXML_Parser_t *parser, void *context) { NW_Status_t status = NW_STAT_SUCCESS; NW_TinyTree_Node_t* attr_node; NW_TinyDom_Parser_t *tiny_parser = (NW_TinyDom_Parser_t*)context; switch(GET_STATE(tiny_parser)){ case T_PARSE_S_TAG_START: case T_PARSE_S_ATTR_START: case T_PARSE_S_ATTR_VALS: if((tiny_parser->state & T_PARSE_FLAG_ATTR) != T_PARSE_FLAG_ATTR){ tiny_parser->state |= T_PARSE_FLAG_ATTR; switch (GET_PASS(tiny_parser)){ case T_PARSE_PASS_1: tiny_parser->node_count++; break; case T_PARSE_PASS_2: attr_node = NW_TinyTree_createChild(&(tiny_parser->dom_tree->tree), tiny_parser->current_node, (NW_TinyTree_Offset_t)parser->offset); if (attr_node != NULL){ NW_TinyTree_Node_setUserFlags(attr_node, T_DOM_NODE_ATTR); } else{ status = NW_STAT_OUT_OF_MEMORY; } break; default: NW_ASSERT(NW_FALSE); status = NW_STAT_FAILURE; } } SET_STATE(tiny_parser, T_PARSE_S_ATTR_START); break; default: status = NW_STAT_FAILURE; } return status; }
NwRcT nwGtpv2cMsgNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle, NW_IN NwU8T teidPresent, NW_IN NwU8T msgType, NW_IN NwU32T teid, NW_IN NwU32T seqNum, NW_OUT NwGtpv2cMsgHandleT *phMsg) { NwGtpv2cStackT* pStack = (NwGtpv2cStackT*) hGtpcStackHandle; NwGtpv2cMsgT *pMsg; NW_ASSERT(pStack); if(gpGtpv2cMsgPool) { pMsg = gpGtpv2cMsgPool; gpGtpv2cMsgPool = gpGtpv2cMsgPool->next; } else { NW_GTPV2C_MALLOC(pStack, sizeof(NwGtpv2cMsgT), pMsg, NwGtpv2cMsgT*); } if(pMsg) { pMsg->version = NW_GTP_VERSION; pMsg->teidPresent = teidPresent; pMsg->msgType = msgType; pMsg->teid = teid; pMsg->seqNum = seqNum; pMsg->msgLen = (NW_GTPV2C_EPC_SPECIFIC_HEADER_SIZE - (teidPresent ? 0 : 4)); pMsg->groupedIeEncodeStack.top = 0; pMsg->hStack = hGtpcStackHandle; *phMsg = (NwGtpv2cMsgHandleT) pMsg; NW_LOG(pStack, NW_LOG_LEVEL_DEBG, "Created message %p!", pMsg); return NW_OK; } return NW_FAILURE; }
NW_Status_t NW_DOM_AttrVal_initFromExtensionInt (NW_DOM_AttrVal_t* val, NW_Uint16 token, NW_Uint32 x) { NW_Uint8 t = (NW_Uint8)token; NW_ASSERT(val != NULL); if ((t == NW_WBXML_EXT_T_0) || (t == NW_WBXML_EXT_T_1) || (t == NW_WBXML_EXT_T_2)) { val->type = NW_WBXML_ATTR_COMPONENT_EXT; val->component.ext.type = NW_TINYDOM_EXTENSION_TYPE_EXT_T_INTEGER; val->component.ext.token = token; val->component.ext.value.x = x; return NW_STAT_SUCCESS; } return NW_STAT_FAILURE; }
static NwGtpv1uRcT nwGtpv1uTrxnStartPeerRspTimer(NwGtpv1uTrxnT *thiz, NwGtpv1uRcT (*timeoutCallbackFunc)(void *)) { NwGtpv1uRcT rc; NwGtpv1uTimeoutInfoT *timeoutInfo; NW_ASSERT(thiz->pStack->tmrMgr.tmrStartCallback != NULL); timeoutInfo = &thiz->peerRspTimeoutInfo; timeoutInfo->timeoutArg = thiz; timeoutInfo->timeoutCallbackFunc = timeoutCallbackFunc; timeoutInfo->hStack = (NwGtpv1uStackHandleT)thiz->pStack; rc = thiz->pStack->tmrMgr.tmrStartCallback(thiz->pStack->tmrMgr.tmrMgrHandle, thiz->t3Timer, 0, NW_GTPV1U_TMR_TYPE_ONE_SHOT, (void *)timeoutInfo, &thiz->hRspTmr); return rc; }
NwRcT nwGtpv2cMsgGetIeTV4( NW_IN NwGtpv2cMsgHandleT hMsg, NW_IN NwU8T type, NW_IN NwU8T instance, NW_OUT NwU32T* pVal) { NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg; NwGtpv2cIeTv4T *pIe; NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM); if(thiz->isIeValid[type][instance]) { pIe = (NwGtpv2cIeTv4T*) thiz->pIe[type][instance]; if(ntohs(pIe->l) != 0x04) return NW_GTPV2C_IE_INCORRECT; if(pVal) *pVal = ntohl(pIe->v); return NW_OK; } return NW_GTPV2C_IE_MISSING; }
EXPORT_C NW_DOM_TextItemType_t NW_DOM_TextItem_getType(NW_DOM_TextItem_t *item) { NW_ASSERT(item != NULL); switch(item->type) { case NW_WBXML_ATTR_COMPONENT_EXT: return NW_DOM_TEXT_ITEM_EXTENSION; case NW_WBXML_ATTR_COMPONENT_STRING: return NW_DOM_TEXT_ITEM_STRING; case NW_WBXML_ATTR_COMPONENT_ENTITY: return NW_DOM_TEXT_ITEM_ENTITY; case NW_WBXML_ATTR_COMPONENT_OPAQUE: return NW_DOM_TEXT_ITEM_OPAQUE; default: return 0; } }
EXPORT_C NW_Uint16 NW_DOM_AttrVal_getType(NW_DOM_AttrVal_t *val) { NW_ASSERT(val != NULL); switch(val->type) { case NW_WBXML_ATTR_COMPONENT_EXT: return NW_DOM_ATTR_VAL_EXTENSION; case NW_WBXML_ATTR_COMPONENT_STRING: return NW_DOM_ATTR_VAL_STRING; case NW_WBXML_ATTR_COMPONENT_ENTITY: return NW_DOM_ATTR_VAL_ENTITY; case NW_WBXML_ATTR_COMPONENT_TOKEN: return NW_DOM_ATTR_VAL_TOKEN; case NW_WBXML_ATTR_COMPONENT_OPAQUE: return NW_DOM_ATTR_VAL_OPAQUE; default: return 0; } }
NwRcT nwGtpv2cMsgGetIeTV8( NW_IN NwGtpv2cMsgHandleT hMsg, NW_IN NwU8T type, NW_IN NwU8T instance, NW_OUT NwU64T* pVal) { NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg; NwGtpv2cIeTv8T *pIe; NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM); if(thiz->isIeValid[type][instance]) { pIe = (NwGtpv2cIeTv8T*) thiz->pIe[type][instance]; if(ntohs(pIe->l) != 0x08) return NW_GTPV2C_IE_INCORRECT; if(pVal) *pVal = NW_NTOHLL((pIe->v)); return NW_OK; } NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Cannot retrieve IE of type %u instance %u !", type, instance); return NW_GTPV2C_IE_MISSING; }
NwRcT nwSaeGwUeFsmRun(NwSaeGwUeFsmT* thiz, NwSaeGwUeT* pUe, NwSaeGwUeEventInfoT* pEv, NwUeStateT* pUeState) { NwRcT rc; NwSaeUeStateT *pState; NW_ASSERT(thiz); NW_FSM_ENTER(); *pUeState = (pUe->state); pState = thiz->pState[pUe->state]; if(pState) { rc = nwSaeGwStateHandleEvent(pState, pUe, pEv); if(*pUeState != pUe->state) { /* Exit the Current State */ if(pState->exit) pState->exit(pUe, pEv); pState = thiz->pState[pUe->state]; /* Enter the next State */ if(pState && pState->enter) pState->enter(pUe, pEv); } } else { rc = nwSaeGwUeUnexpectedEvent(pUe, pEv); } *pUeState = (pUe->state); NW_FSM_LEAVE(); return rc; }
static void NW_TMR_CALLBACK(nwMiniTmrMgrHandleTimeout) { NwRcT rc; #ifdef __WITH_LIBEVENT__ NwMiniTmrMgrEntityT *pTmr = (NwMiniTmrMgrEntityT*) arg; /*--------------------------------------------------------------------------- * Send Timeout Request to GRE Stack Instance *--------------------------------------------------------------------------*/ rc = nwGreProcessTimeout(pTmr->timeoutArg); NW_ASSERT( NW_OK == rc ); free(pTmr); #else #warning "Timer library not defined!" #endif return; }
/**************************************************************************** * Name: NW_TinyDom_ParserInitialize * Description: Helper function to initialize the parser * * Parameters: p -- pointer to a Parser_t struct * dictionaries -- pointer to the WBXML dictionaries * dictionaryCount -- number of dictionaries * * Algorithm: This is just a wrapper to conceal unnecessary initialization details. * Return value: NW_STAT_SUCCESS, NW_STAT_FAILURE, NW_STAT_OUT_OF_MEMORY ***************************************************************************/ EXPORT_C NW_Status_t NW_TinyDom_ParserInitialize(Parser_t *p, NW_WBXML_Dictionary_t * dictionaries[], NW_Int32 dictionaryCount, NW_Uint32 default_public_id) { NW_Status_t status; NW_ASSERT(p != NULL); (void) NW_Mem_memset(p, 0, sizeof(*p)); /* Initialize the dictionary to use */ if (dictionaries){ status = NW_WBXML_Dictionary_add( dictionaryCount, dictionaries ); if (status == NW_STAT_FAILURE) { status = NW_WBXML_Dictionary_initialize (dictionaryCount, dictionaries); if (status != NW_STAT_SUCCESS) { return status; } } } /* create the WBXML Parser */ NW_WBXML_Parser_newInPlace (&(p->wbxmlParser)); status = NW_WBXML_Document_construct(&(p->document), default_public_id); /* This ASSERT removed for "out of memory" testing using CXML Testkit component */ // NW_ASSERT(status == NW_STAT_SUCCESS); if (status == NW_STAT_SUCCESS){ /* initialize the TinyDOM stuff */ NW_TinyDom_Tree_construct (&(p->tinyDOMTree), &(p->wbxmlParser), &(p->document), &(p->writer)); NW_TinyDom_Parser_construct (&(p->tinyParser), &(p->tinyDOMTree)); } return status; }
NwRcT nwGtpv2cMsgGroupedIeStart(NW_IN NwGtpv2cMsgHandleT hMsg, NW_IN NwU8T type, NW_IN NwU8T instance) { NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg; NwGtpv2cIeTlvT *pIe; pIe = (NwGtpv2cIeTlvT*) (pMsg->msgBuf + pMsg->msgLen); pIe->t = type; pIe->i = instance & 0x00ff; pMsg->msgLen += (4); pIe->l = (pMsg->msgLen); NW_ASSERT(pMsg->groupedIeEncodeStack.top < NW_GTPV2C_MAX_GROUPED_IE_DEPTH); pMsg->groupedIeEncodeStack.pIe[pMsg->groupedIeEncodeStack.top] = pIe; pMsg->groupedIeEncodeStack.top++; return NW_OK; }
static NwGtpv1uRcT nwGtpv1uSendto( NwGtpv1uStackT *thiz, NW_IN NwGtpv1uUlpApiT *pUlpReq) { NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; NW_ASSERT(thiz); #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_ENTER(thiz); #endif (void) nwGtpv1uMsgSetTeid(pUlpReq->apiInfo.sendtoInfo.hMsg, pUlpReq->apiInfo.sendtoInfo.teid); rc = nwGtpv1uCreateAndSendMsg(thiz, pUlpReq->apiInfo.sendtoInfo.ipAddr, 2152, (NwGtpv1uMsgT *) (NwGtpv1uMsgT *) pUlpReq->apiInfo.sendtoInfo.hMsg); #if defined(LOG_GTPU) && LOG_GTPU > 0 NW_LEAVE(thiz); #endif return rc; }
NwRcT nwGtpv2cMsgGetIeTlv( NW_IN NwGtpv2cMsgHandleT hMsg, NW_IN NwU8T type, NW_IN NwU8T instance, NW_IN NwU16T maxLen, NW_OUT NwU8T* pVal, NW_OUT NwU16T* pLen) { NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg; NwGtpv2cIeTlvT *pIe; NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM); if(thiz->isIeValid[type][instance]) { pIe = (NwGtpv2cIeTlvT*) thiz->pIe[type][instance]; if(ntohs(pIe->l) <= maxLen) { if(pVal) memcpy(pVal, ((NwU8T*) pIe) + 4, ntohs(pIe->l)); if(pLen) *pLen = ntohs(pIe->l); return NW_OK; } } return NW_GTPV2C_IE_MISSING; }
NwSdpRcT nwSdpSetGreServiceTransportInterface( NW_IN NwSdpHandleT hSdp, NW_IN NwSdpServiceHandleT hSdpService, NW_IN NwU32T hGreTlInterface, NW_IN NwSdpRcT (*pGreTlDataReqCb)(NwU32T udpHandle, NwU8T* dataBuf, NwU32T dataSize, NwU32T peerIpAddr, NwU32T peerPort)) { NwSdpRcT rc; NwGreLlpEntityT greLlp; NwGreStackHandleT hGreStack = (NwGreStackHandleT) hSdpService; NwSdpT* thiz = (NwSdpT*) hSdp; greLlp.hUdp = (NwGreUdpHandleT) hGreTlInterface; greLlp.udpDataReqCallback = pGreTlDataReqCb; rc = nwGreSetUdpEntity(hGreStack, &greLlp); NW_ASSERT( rc == NW_SDP_OK ); return rc; }
NwSaeGwUeFsmT* NwSaeGwUeFsmNew() { NwRcT rc; NwSaeGwUeFsmT* thiz; NW_FSM_ENTER(); if(gpSaeGwFsm) { thiz = gpSaeGwFsm; } else { thiz = (NwSaeGwUeFsmT*) nwMemNew (sizeof(NwSaeGwUeFsmT)); memset(thiz, 0x00, sizeof(NwSaeGwUeFsmT)); /* Initialize states */ thiz->pState[NW_SAE_GW_UE_STATE_INIT] = nwSaeGwStateInitNew(); thiz->pState[NW_SAE_GW_UE_STATE_SAE_SESSION_CREATED] = nwSaeGwStateSaeSessionCreatedNew(); thiz->pState[NW_SAE_GW_UE_STATE_SGW_SESSION_CREATED] = nwSaeGwStateSgwSessionCreatedNew(); thiz->pState[NW_SAE_GW_UE_STATE_PGW_SESSION_CREATED] = nwSaeGwStatePgwSessionCreatedNew(); thiz->pState[NW_SAE_GW_UE_STATE_SAE_SESSION_ESTABLISHED] = nwSaeGwStateSaeSessionEstablishedNew(); thiz->pState[NW_SAE_GW_UE_STATE_SGW_SESSION_ESTABLISHED] = nwSaeGwStateSgwSessionEstablishedNew(); thiz->pState[NW_SAE_GW_UE_STATE_WT_PGW_CREATE_SESSION_RSP] = nwSaeGwStateAwaitPgwCreateSessionRspNew(); thiz->pState[NW_SAE_GW_UE_STATE_WT_PGW_DELETE_SESSION_RSP] = nwSaeGwStateAwaitPgwDeleteSessionRspNew(); rc = nwSaeGwStateSetParentState(thiz->pState[NW_SAE_GW_UE_STATE_SGW_SESSION_CREATED], thiz->pState[NW_SAE_GW_UE_STATE_SAE_SESSION_CREATED]); NW_ASSERT( NW_OK == rc ); gpSaeGwFsm = thiz; } NW_FSM_LEAVE(); return thiz; }
static NW_Status_t Tag_Start_CB (NW_WBXML_Parser_t *parser, void *context) { NW_TinyDom_Parser_t *tiny_parser = (NW_TinyDom_Parser_t*)context; NW_Status_t s = NW_STAT_FAILURE; switch(GET_PASS(tiny_parser)){ case T_PARSE_PASS_1: s = Pass_1_Tag_Start_CB(parser, context); break; case T_PARSE_PASS_2: s = Pass_2_Tag_Start_CB(parser, context); break; default: NW_ASSERT(NW_FALSE); } SET_STATE(tiny_parser, T_PARSE_S_TAG_START); tiny_parser->state &= ~T_PARSE_FLAG_TEXT; /* No longer accumulating text */ tiny_parser->state &= ~T_PARSE_FLAG_ATTR; /* Turn off attribute flag */ return s; }
EXPORT_C NW_Status_t NW_TinyDom_AppendDOMTree (Parser_t *p, NW_Byte *buffer, NW_Uint32 length, NW_Uint32 cp_count, NW_Int32 lastValid, NW_DOM_DocumentNode_t **root) { NW_Status_t status; NW_ASSERT(p != NULL); /* build the tinyDOM tree */ //p->wbxmlParser.offset = p->wbxmlParser.lastValid; p->wbxmlParser.offset = NW_TinyDom_getLastValid(p->tinyParser.dom_tree); p->tinyParser.cp_count = cp_count; //p->wbxmlParser.lastValid = lastValid; status = NW_TinyDom_Parser_incrementalBuildTree (&(p->tinyParser), (char *)buffer, length, NW_FALSE, lastValid); if ((status == NW_STAT_SUCCESS) && (root != NULL)) { *root = p->tinyDOMTree.root_node; } return status; }
void NW_TinyDom_setLastValid(NW_TinyDom_Tree_t* dom_tree, NW_Int32 lastValid) { NW_ASSERT(dom_tree->tree.tree != NULL); dom_tree->tree.tree->lastValid = lastValid; }
/* ------------------------------------------------------------------------- */ EXPORT_C NW_Status_t NW_Encoder_encodeWBXML(NW_Encoder_t* encoder, NW_DOM_DocumentNode_t * docNode, NW_Bool enableStringTable, NW_Uint32 *length, NW_Byte **buffer) { NW_Status_t status; NW_DOM_ElementNode_t *elem; NW_Uint32 publicid; NW_WBXML_Dictionary_t* dictionary; if ((encoder == NULL) || (docNode == NULL)){ return NW_STAT_BAD_INPUT_PARAM; } status = NW_Encoder_initialize(encoder, enableStringTable); if (status != NW_STAT_SUCCESS){ return status; } encoder->encoding = NW_DOM_DocumentNode_getCharacterEncoding(docNode); elem = NW_DOM_DocumentNode_getDocumentElement(docNode); publicid = NW_DOM_DocumentNode_getPublicIdAsNumber(docNode); /* initialize WBXMLWriter */ if (publicid != 0){ dictionary = NW_WBXML_Dictionary_getByPublicId(publicid); } else { NW_String_t docType; status = NW_DOM_DocumentNode_getPublicId(docNode, &docType); if (status != NW_STAT_SUCCESS){ return status; } dictionary = NW_WBXML_Dictionary_getByDocType(&docType, encoder->encoding); } if (enableStringTable == NW_TRUE) { /* assuming that same dictionary is used for both attributes and tags */ status = NW_Encoder_StringTable_createFromDOM(encoder->stringTable, docNode, dictionary); if (status != NW_STAT_SUCCESS){ return status; } } /* Set up the writer for a sizing pass */ NW_WBXML_Writer_SetToSizing(&encoder->writer); NW_WBXML_Writer_Initialize(&encoder->writer, 0, NULL, NULL, dictionary, dictionary, ((enableStringTable == NW_TRUE) ? NW_Encoder_StringTable_getStringTableOffset : NULL), ((enableStringTable == NW_TRUE) ? NW_Encoder_StringTable_addToStringTable : NULL), ((enableStringTable == NW_TRUE) ? encoder->stringTable : NULL), ((enableStringTable == NW_TRUE) ? NW_Encoder_StringTable_StringTableIterateInit : NULL), ((enableStringTable == NW_TRUE) ? NW_Encoder_StringTable_StringTableIterateNext : NULL), NW_TRUE /* sizing only */); status = NW_Encoder_encodeDocHeader(encoder, docNode); if (status != NW_STAT_SUCCESS){ return status; } status = NW_Encoder_encodeNode(encoder, elem); /* Allocate a buffer of the correct size */ *length = (CXML_Vector_Metric_t)NW_WBXML_Writer_GetSize(&encoder->writer); *buffer = (NW_Byte*)NW_Mem_Malloc(*length); if (*buffer == NULL){ return NW_STAT_OUT_OF_MEMORY; } /* Set up the writer for a writing pass */ NW_WBXML_Writer_SetToWrite(&encoder->writer, *length, *buffer); status = NW_Encoder_encodeDocHeader(encoder, docNode); if (status != NW_STAT_SUCCESS){ return status; } status = NW_Encoder_encodeNode(encoder, elem); NW_ASSERT(status == NW_STAT_SUCCESS); NW_Encoder_StringTable_delete(encoder->stringTable); return NW_STAT_SUCCESS; }
NwRcT nwIpv4IfInitialize(NwIpv4IfT* thiz, NwU8T* device, NwSdpHandleT hSdp, NwU8T *pHwAddr) { int sd, send_sd; struct sockaddr_ll sll; struct ifreq ifr; /* * Create Socket for listening IP packets */ sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); if (sd < 0) { NW_IP_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno)); NW_ASSERT(0); } bzero(&sll, sizeof(sll)); bzero(&ifr, sizeof(ifr)); /* First Get the Interface Index */ strncpy((char *)ifr.ifr_name, (const char*)device, IFNAMSIZ); if((ioctl(sd, SIOCGIFHWADDR, &ifr)) == -1) { printf("Error getting Interface hw address!\n"); exit(-1); } else { #if 0 printf("HW address of interface is: %02x:%02x:%02x:%02x:%02x:%02x\n", (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[0], (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[1], (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[2], (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[3], (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[4], (unsigned char)ifr.ifr_ifru.ifru_hwaddr.sa_data[5]); #endif memcpy(pHwAddr, ifr.ifr_hwaddr.sa_data, 6); memcpy(thiz->hwAddr, ifr.ifr_hwaddr.sa_data, 6); } if((ioctl(sd, SIOCGIFINDEX, &ifr)) == -1) { printf("Error getting Interface index !\n"); exit(-1); } thiz->ifindex = ifr.ifr_ifindex; /* Bind our raw socket to this interface */ sll.sll_family = PF_PACKET; sll.sll_ifindex = ifr.ifr_ifindex; sll.sll_protocol = htons(ETH_P_IP); if((bind(sd, (struct sockaddr *)&sll, sizeof(sll)))== -1) { printf("Error binding raw socket to interface\n"); exit(-1); } thiz->hRecvSocketIpv4 = sd; thiz->hSdp = hSdp; /* * Create Socket for listening ARP requests */ sd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); if (sd < 0) { NW_IP_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno)); NW_ASSERT(0); } bzero(&sll, sizeof(sll)); bzero(&ifr, sizeof(ifr)); /* First Get the Interface Index */ strncpy((char *)ifr.ifr_name, (const char*)device, IFNAMSIZ); if((ioctl(sd, SIOCGIFINDEX, &ifr)) == -1) { printf("Error getting Interface index !\n"); exit(-1); } /* Bind our raw socket to this interface */ sll.sll_family = PF_PACKET; sll.sll_ifindex = ifr.ifr_ifindex; sll.sll_protocol = htons(ETH_P_ARP); if((bind(sd, (struct sockaddr *)&sll, sizeof(sll)))== -1) { printf("Error binding raw socket to interface\n"); exit(-1); } thiz->hRecvSocketArp = sd; /* * Create socket sending data to L2 */ if((send_sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))== -1) { printf("Error creating raw socket: send fd"); exit(1); } int yes = 1; if(setsockopt(send_sd, IPPROTO_IP, IP_HDRINCL, &yes, sizeof(yes)) < 0 ) { perror("Error in Setting socket option:"); exit(1); } thiz->hSendSocket = send_sd; return NW_OK; }
/* ------------------------------------------------------------------------- */ static NW_Status_t NW_Encoder_encodeElementNode(NW_Encoder_t * encoder, NW_DOM_ElementNode_t * e) { NW_Status_t status; NW_DOM_AttributeListIterator_t listIterator; NW_DOM_AttributeHandle_t attrHandle; NW_Uint16 fqToken; NW_Uint8 token; NW_Uint32 tagIndex; NW_Int32 charCount; if ((encoder == NULL) || (e == NULL)){ return NW_STAT_BAD_INPUT_PARAM; } fqToken = NW_DOM_ElementNode_getTagToken(e); token = (NW_Uint8)(fqToken & NW_WBXML_MASK_TOKEN); if (token == NW_WBXML_LITERAL) { NW_String_t elementName; if (NW_DOM_ElementNode_getTagName(e, &elementName) != NW_STAT_SUCCESS){ return NW_STAT_FAILURE; } /*Get the char count */ charCount = NW_String_charBuffGetLength(elementName.storage, encoder->encoding, &(elementName.length) ); status = NW_WBXML_Writer_TagString(&encoder->writer, encoder->encoding, charCount, elementName.length, elementName.storage, &tagIndex); /* Do not free literal element here as this will be freed when literal table * will be freed. */ // NW_String_delete(&elementName); } else{ status = NW_WBXML_Writer_TagToken(&encoder->writer, fqToken, &tagIndex); NW_ASSERT(status == NW_STAT_SUCCESS); } if (NW_DOM_Node_getFirstChild(e)){ status = NW_WBXML_Writer_TagSetContentFlag(&encoder->writer, tagIndex); NW_ASSERT(status == NW_STAT_SUCCESS); } if (NW_DOM_ElementNode_hasAttributes(e)){ status = NW_WBXML_Writer_TagSetAttributesFlag(&encoder->writer, tagIndex); NW_ASSERT(status == NW_STAT_SUCCESS); } if (status != NW_STAT_SUCCESS){ return status; } if (NW_DOM_ElementNode_hasAttributes(e)) { status = NW_DOM_ElementNode_getAttributeListIterator(e, &listIterator); if (status != NW_STAT_SUCCESS){ return status; } while (NW_DOM_AttributeListIterator_getNextAttribute(&listIterator, &attrHandle) == NW_STAT_WBXML_ITERATE_MORE) { NW_Encoder_encodeAttribute(encoder, &attrHandle); } return NW_WBXML_Writer_End(&encoder->writer); } return NW_STAT_SUCCESS; }
/* ------------------------------------------------------------------------- */ static NW_Status_t NW_Encoder_encodeAttrVal(NW_Encoder_t * encoder, NW_DOM_AttrVal_t *val) { NW_Status_t status; if ((encoder == NULL) || (val == NULL)){ return NW_STAT_BAD_INPUT_PARAM; } status = NW_STAT_SUCCESS; switch(NW_DOM_AttrVal_getType(val)) { case NW_DOM_ATTR_VAL_STRING: { status = NW_WBXML_Writer_Text(&encoder->writer, encoder->encoding, val->component.string.length, val->component.string.storage); break; } case NW_DOM_ATTR_VAL_EXTENSION: { NW_Uint8 t; /* 8-bit token */ NW_String_t str; t = (NW_Uint8)(val->component.ext.token); if ((t == NW_WBXML_EXT_0) || (t == NW_WBXML_EXT_1) || (t == NW_WBXML_EXT_2)) { status = NW_WBXML_Writer_Extension(&encoder->writer, (NW_Uint16)(val->component.ext.token), 0, 0, NULL); } else if ((t == NW_WBXML_EXT_T_0) || (t == NW_WBXML_EXT_T_1) || (t == NW_WBXML_EXT_T_2)) { NW_ASSERT((val->component.ext.type == NW_TINYDOM_EXTENSION_TYPE_NORMAL) || (val->component.ext.type == NW_TINYDOM_EXTENSION_TYPE_EXT_T_INTEGER)); if (val->component.ext.type == NW_TINYDOM_EXTENSION_TYPE_NORMAL) { NW_Uint16 token = NW_DOM_TextItem_getExtension(val, &str); status = NW_WBXML_Writer_ExtensionUseStringTable(&encoder->writer, token, str.length, str.storage); } else { status = NW_WBXML_Writer_Extension(&encoder->writer, (NW_Uint16)(val->component.ext.token), val->component.ext.value.x, 0, NULL); } } else if ((t == NW_WBXML_EXT_I_0) || (t == NW_WBXML_EXT_I_1) || (t == NW_WBXML_EXT_I_2)) { NW_Uint16 token = NW_DOM_TextItem_getExtension(val, &str); status = NW_WBXML_Writer_Extension(&encoder->writer, token, 0, str.length, str.storage); } else { status = NW_STAT_FAILURE; } break; } case NW_DOM_ATTR_VAL_ENTITY: { NW_Uint32 entity; entity = NW_DOM_TextItem_getEntity(val); status = NW_WBXML_Writer_Entity(&encoder->writer, entity); break; } case NW_DOM_ATTR_VAL_OPAQUE: { NW_Uint32 length; NW_Byte *data; data = NW_DOM_AttrVal_getOpaque(val, &length); status = NW_WBXML_Writer_Opaque(&encoder->writer, length, data); break; } case NW_DOM_ATTR_VAL_TOKEN: { NW_Uint16 fqToken = NW_DOM_AttrVal_getToken(val); status = NW_WBXML_Writer_AttributeToken(&encoder->writer, fqToken); break; } default: return NW_STAT_FAILURE; } return status; }
EXPORT_C NW_Status_t NW_DOM_AttrVal_toString(NW_DOM_AttrVal_t *av, NW_String_t * string, NW_Uint32 encoding) { NW_Status_t status; NW_ASSERT(av != NULL); NW_ASSERT(string != NULL); NW_String_initialize(string, NULL, 0); if ((NW_String_charsetValid(encoding)) != NW_STAT_SUCCESS) return NW_STAT_WBXML_ERROR_CHARSET_UNSUPPORTED; switch (NW_DOM_AttrVal_getType(av)) { case NW_DOM_ATTR_VAL_TOKEN: status = NW_String_tokenToString(av->component.value_token, string, encoding); if(status != NW_STAT_SUCCESS){ return NW_STAT_DOM_NO_STRING_RETURNED; } return NW_STAT_SUCCESS; case NW_DOM_ATTR_VAL_STRING: { NW_Byte *storage = av->component.string.storage; status = NW_String_initialize(string, storage, encoding); if(status != NW_STAT_SUCCESS){ return NW_STAT_DOM_NO_STRING_RETURNED; } return NW_STAT_SUCCESS; } case NW_DOM_ATTR_VAL_ENTITY: status = NW_String_entityToString(av->component.entity, string, encoding); if(status != NW_STAT_SUCCESS){ return NW_STAT_DOM_NO_STRING_RETURNED; } return NW_STAT_SUCCESS; case NW_DOM_ATTR_VAL_OPAQUE: return NW_STAT_DOM_NO_STRING_RETURNED; case NW_DOM_ATTR_VAL_EXTENSION: { NW_Uint8 t; /* 8-bit token */ t = (NW_Uint8)(av->component.ext.token); if ((t == NW_WBXML_EXT_0) || (t == NW_WBXML_EXT_1) || (t == NW_WBXML_EXT_2)) { return NW_STAT_DOM_NO_STRING_RETURNED; } if (av->component.ext.value.string.storage == NULL) { return NW_STAT_DOM_NO_STRING_RETURNED; } /* struct assignment, shallow copy */ *string = av->component.ext.value.string; return NW_STAT_SUCCESS; } default: return NW_STAT_DOM_NO_STRING_RETURNED; } }
/** * Send msg to peer via data request to UDP Entity * * @param[in] thiz : Pointer to stack. * @param[in] pTrxn : Pointer to Trxn object. * @param[in] peerIp : Peer Ip address. * @param[in] peerPort : Peer Ip port. * @param[in] pMsg : Message to be sent. * @return NW_GTPV1U_OK on success. */ NwGtpv1uRcT nwGtpv1uTrxnCreateAndSendMsg( NW_IN NwGtpv1uStackT *thiz, NW_IN NwGtpv1uTrxnT *pTrxn, NW_IN uint32_t peerIp, NW_IN uint32_t peerPort, NW_IN NwGtpv1uMsgT *pMsg) { NwGtpv1uRcT rc; uint8_t *msgHdr; NW_ASSERT(thiz); NW_ASSERT(pMsg); msgHdr = &pMsg->msgBuf[pMsg->msgBufOffset]; NW_ASSERT(msgHdr != NULL); *(msgHdr++) = (pMsg->version << 5) | (pMsg->protocolType << 4) | (pMsg->extHdrFlag << 2) | (pMsg->seqNumFlag << 1) | (pMsg->npduNumFlag); *(msgHdr++) = (pMsg->msgType); *((uint16_t *) msgHdr) = htons(pMsg->msgLen); msgHdr += 2; *((uint32_t *) msgHdr) = htonl(pMsg->teid); msgHdr += 4; if(pMsg->seqNumFlag | pMsg->extHdrFlag | pMsg->npduNumFlag) { if(pMsg->seqNumFlag) { *((uint16_t *) msgHdr) = htons((pTrxn ? pTrxn->seqNum : pMsg->seqNum)); } else { *((uint16_t *) msgHdr) = 0x0000; } msgHdr += 2; if(pMsg->npduNumFlag) { *((uint8_t *) msgHdr) = pMsg->npduNumFlag; } else { *((uint8_t *) msgHdr) = 0x00; } msgHdr++; if(pMsg->extHdrFlag) { *((uint8_t *) msgHdr) = pMsg->extHdrFlag; } else { *((uint8_t *) msgHdr) = 0x00; } msgHdr++; } NW_ASSERT(thiz->udp.udpDataReqCallback != NULL); rc = thiz->udp.udpDataReqCallback(thiz->udp.hUdp, pMsg->msgBuf, pMsg->msgLen, pMsg->msgBufOffset, peerIp, peerPort); /* Save the message for retransmission */ if(rc == NW_GTPV1U_OK && pTrxn) { pTrxn->pMsg = pMsg; pTrxn->peerIp = peerIp; pTrxn->peerPort = peerPort; rc = nwGtpv1uTrxnStartPeerRspTimer(pTrxn, nwGtpv1uTrxnPeerRspTimeout); NW_ASSERT(rc == NW_GTPV1U_OK); } return rc; }
NwRcT nwGtpv2cMsgParserRun( NW_IN NwGtpv2cMsgParserT* thiz, NW_IN NwGtpv2cMsgHandleT hMsg, NW_OUT NwU8T *pOffendingIeType, NW_OUT NwU8T *pOffendingIeInstance) { NwRcT rc = NW_OK; NwU8T flags; NwU16T mandatoryIeCount =0; NwGtpv2cIeTlvT *pIe; NwU8T *pIeStart; NwU8T *pIeEnd; NwU16T ieLength; NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg; NW_ASSERT(pMsg); flags = *((NwU8T*)(pMsg->msgBuf)); pIeStart = (NwU8T *) (pMsg->msgBuf + (flags & 0x08 ? 12: 8)); pIeEnd = (NwU8T *) (pMsg->msgBuf + pMsg->msgLen); memset(thiz->pIe, 0, sizeof(NwU8T*) * (NW_GTPV2C_IE_TYPE_MAXIMUM) * (NW_GTPV2C_IE_INSTANCE_MAXIMUM)); memset(pMsg->pIe, 0, sizeof(NwU8T*) * (NW_GTPV2C_IE_TYPE_MAXIMUM) * (NW_GTPV2C_IE_INSTANCE_MAXIMUM)); while (pIeStart < pIeEnd) { pIe = (NwGtpv2cIeTlvT*) pIeStart; ieLength = ntohs(pIe->l); if(pIeStart + 4 + ieLength > pIeEnd) { *pOffendingIeType = pIe->t; *pOffendingIeInstance = pIe->i; return NW_GTPV2C_MSG_MALFORMED; } if((thiz->ieParseInfo[pIe->t][pIe->i].iePresence)) { thiz->pIe[pIe->t][pIe->i] = (NwU8T*) pIeStart; pMsg->pIe[pIe->t][pIe->i] = (NwU8T*) pIeStart; NW_LOG(thiz->hStack, NW_LOG_LEVEL_DEBG, "Received IE %u of length %u!", pIe->t, ieLength); if((thiz->ieParseInfo[pIe->t][pIe->i].ieReadCallback) != NULL ) { rc = thiz->ieParseInfo[pIe->t][pIe->i].ieReadCallback(pIe->t, ieLength, pIe->i, pIeStart + 4, thiz->ieParseInfo[pIe->t][pIe->i].ieReadCallbackArg); if(NW_OK == rc) { if(thiz->ieParseInfo[pIe->t][pIe->i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY) mandatoryIeCount++; } else { NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Error while parsing IE %u with instance %u and length %u!", pIe->t, pIe->i, ieLength); break; } } else { if((thiz->ieReadCallback) != NULL ) { NW_LOG(thiz->hStack, NW_LOG_LEVEL_DEBG, "Received IE %u of length %u!", pIe->t, ieLength); rc = thiz->ieReadCallback(pIe->t, ieLength, pIe->i, pIeStart + 4, thiz->ieReadCallbackArg); if(NW_OK == rc) { if(thiz->ieParseInfo[pIe->t][pIe->i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY) mandatoryIeCount++; } else { NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Error while parsing IE %u of length %u!", pIe->t, ieLength); break; } } else { NW_LOG(thiz->hStack, NW_LOG_LEVEL_WARN, "No parse method defined for received IE type %u of length %u in message %u!", pIe->t, ieLength, thiz->msgType); } } } else { NW_LOG(thiz->hStack, NW_LOG_LEVEL_WARN, "Unexpected IE %u of length %u received in msg %u!", pIe->t, ieLength, thiz->msgType); } pIeStart += (ieLength + 4); } if((NW_OK == rc) && (mandatoryIeCount != thiz->mandatoryIeCount)) { NwU16T t, i; *pOffendingIeType = 0; *pOffendingIeInstance = 0; for(t = 0; t < NW_GTPV2C_IE_TYPE_MAXIMUM; t++) { for(i = 0; i < NW_GTPV2C_IE_INSTANCE_MAXIMUM; i ++) { if(thiz->ieParseInfo[t][i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY) { if(thiz->pIe[t][i] == NULL) { *pOffendingIeType = t; *pOffendingIeInstance = i; return NW_GTPV2C_MANDATORY_IE_MISSING; } } } } NW_LOG(thiz->hStack, NW_LOG_LEVEL_WARN, "Unknown mandatory IE missing. Parser formed incorrectly! %u:%u", mandatoryIeCount, thiz->mandatoryIeCount); return NW_GTPV2C_MANDATORY_IE_MISSING; } return rc; }
EXPORT_C NW_Status_t NW_DOM_TextNode_getData(NW_DOM_TextNode_t *node, NW_String_t *valueString) { NW_Status_t status; NW_DOM_TextItemIterator_t iterator; NW_String_t str; NW_DOM_TextItem_t item; NW_DOM_DocumentNode_t *docNode; NW_Uint32 encoding; NW_ASSERT(node != NULL); NW_ASSERT(valueString != NULL); docNode = NW_DOM_Node_getOwnerDocument(node); encoding = NW_DOM_DocumentNode_getCharacterEncoding(docNode); if (NW_DOM_Node_getNodeType(node) != NW_DOM_TEXT_NODE){ return NW_STAT_DOM_NODE_TYPE_ERR; } /* Initializes the handle with values*/ status = NW_DOM_TextNode_getTextItemIterator(node, &iterator); if (status != NW_STAT_SUCCESS){ return status; } valueString->length = 0; valueString->storage = NULL; NW_String_setUserOwnsStorage(valueString); while (NW_DOM_TextItemIterator_getNextTextItem(&iterator, &item) == NW_STAT_WBXML_ITERATE_MORE){ status = NW_DOM_TextItem_toString(&item, &str, encoding); if (status != NW_STAT_SUCCESS){ return status; } if ((valueString->length == 0) || (valueString->storage == NULL)){ status = NW_String_deepCopy(valueString, &str); } else{ status = NW_String_concatenate(valueString, &str, encoding); } if (status != NW_STAT_SUCCESS){ NW_String_deleteStorage(&str); if (status == NW_STAT_OUT_OF_MEMORY) { return NW_STAT_OUT_OF_MEMORY; } else { return NW_STAT_DOM_NO_STRING_RETURNED; } } } NW_String_deleteStorage(&str); return NW_STAT_SUCCESS; }
EXPORT_C NW_Status_t NW_DOM_TextItem_toString(NW_DOM_TextItem_t *item, NW_String_t *string, NW_Uint32 encoding) { NW_Status_t status; NW_ASSERT(item != NULL); NW_ASSERT(string != NULL); NW_String_initialize(string, NULL, 0); if ((NW_String_charsetValid(encoding)) != NW_STAT_SUCCESS){ return NW_STAT_WBXML_ERROR_CHARSET_UNSUPPORTED; } switch (NW_DOM_TextItem_getType(item)) { case NW_DOM_TEXT_ITEM_STRING: { NW_Byte *storage = item->component.string.storage; status = NW_String_initialize(string, storage, encoding); if(status == NW_STAT_SUCCESS){ return NW_STAT_SUCCESS; } else{ return NW_STAT_DOM_NO_STRING_RETURNED; } } case NW_DOM_TEXT_ITEM_ENTITY: status = NW_String_entityToString(item->component.entity, string, encoding); if(status == NW_STAT_SUCCESS){ return NW_STAT_SUCCESS; } else{ return NW_STAT_DOM_NO_STRING_RETURNED; } case NW_DOM_TEXT_ITEM_OPAQUE: return NW_STAT_DOM_NO_STRING_RETURNED; case NW_DOM_TEXT_ITEM_EXTENSION: { NW_Uint8 t; /* 8-bit token */ t = (NW_Uint8)(item->component.ext.token); if ((t == NW_WBXML_EXT_0) || (t == NW_WBXML_EXT_1) || (t == NW_WBXML_EXT_2)) { return NW_STAT_DOM_NO_STRING_RETURNED; } if ((item->component.ext.type == NW_TINYDOM_EXTENSION_TYPE_EXT_T_INTEGER) && ((t == NW_WBXML_EXT_T_0) || (t == NW_WBXML_EXT_T_1) || (t == NW_WBXML_EXT_T_2))) { return NW_STAT_DOM_NO_STRING_RETURNED; } if (item->component.ext.value.string.storage == NULL) { return NW_STAT_DOM_NO_STRING_RETURNED; } /* struct assignment, shallow copy */ *string = item->component.ext.value.string; return NW_STAT_SUCCESS; } default: return NW_STAT_DOM_NO_STRING_RETURNED; } }