int item_delete(t_list *list, t_item *item) { t_item *current; if (list == NULL || item == NULL) return (-1); current = list_get_head(list); while (current != NULL) { if (current == item) { if (list->head == current) list->head = current->next; if (list->tail == current) list->tail = current->prev; if (current->prev != NULL) current->prev->next = current->next; if (current->next != NULL) current->next->prev = current->prev; free(current); list->len -= 1; return (0); } current = current->next; } return (-1); }
void cli_broadcast(t_request_data *rqd, t_server *t, t_world *w) { t_item *current_item; char response[ANSWER_SIZE]; int direction; (void) w; current_item = list_get_head(t->client_list); while (current_item != NULL) { if ((T_PLAYER(current_item->cont)->protocol == CLI_PROTO) && (T_PLAYER(current_item->cont)->connected == CONNECTED) && T_PLAYER(current_item->cont) != rqd->user) { direction = broadcast_to(T_PLAYER(current_item->cont), rqd, t); sprintf(response, "broadcast %d, %s\n", direction, (char *)rqd->argv[0]); cli_answer(T_PLAYER(current_item->cont), t, response); } current_item = current_item->next; } cli_answer(rqd->user, t, "ok\n"); sprintf(response, "pbc %d %s\n", rqd->user->number, (char*)rqd->argv[0]); free(rqd->argv[0]); free(rqd->argv); cli_answer_to_all_graph(t, response); }
// prepends element to list and returns new head linked_list_t* list_cons(linked_list_t* head, void* data) { linked_list_t* node = malloc(sizeof(linked_list_t)); node->prev = NULL; node->next = list_get_head(head); node->data = data; return node; }
ListNode* list_get_tail(List *l) { ListNode *node = list_get_head(l); if (!node) return NULL; while (node->next) node = node->next; return node; }
void list_free(List *l) { ListNode *node = list_get_head(l), *temp; while (node) { temp = node; node = node->next; free(temp); } }
void print_list(List *l) { ListNode *node = list_get_head(l); printf("\n----\n"); while (node) { printf("%d ", node->data); node = node->next; } printf("\n----\n\n"); }
ListNode* list_get_tail(List *l) { ListNode *node = list_get_head(l); if (!node) return NULL; while (node->next >= 0) node = list_get_next(l, node); ++l->total; return node; }
/* Code coverage test for Node and List functions. */ void test_task_f(void *user_data) { List l; Node n1; Node n2; list_init(&l); n1.prio = 3; n1.name = "one"; n2.prio = 8; n2.name = "two"; assert(true == list_is_empty(&l)); assert(NULL == list_get_head(&l)); list_add_tail(&l, &n1); assert(false == list_is_empty(&l)); assert(&n1 == list_get_head(&l)); list_add_tail(&l, &n2); assert(&n1 == list_get_head(&l)); assert(&n1 == list_find(&l, "one")); assert(&n2 == list_find(&l, "two")); list_rem_head(&l); assert(&n2 == list_get_head(&l)); assert(NULL == list_find(&l, "one")); list_rem_head(&l); list_enqueue(&l, &n1); assert(&n1 == list_get_head(&l)); list_enqueue(&l, &n2); assert(&n2 == list_get_head(&l)); list_unlink(&n1); assert(&n2 == list_get_head(&l)); list_enqueue(&l, &n1); assert(&n2 == list_get_head(&l)); assert(&n2 == list_rem_head(&l)); assert(&n1 == list_rem_head(&l)); assert(NULL == list_rem_head(&l)); assert(NULL == list_rem_head(&l)); assert(3 == n1.prio); assert(8 == n2.prio); assert(NULL == list_find(&l, "one")); assert(NULL == list_find(&l, "two")); test_pass(); }
void mamaStatsGenerator_generateStats (mamaStatsGenerator statsGenerator) { mamaStatsGeneratorImpl* impl = (mamaStatsGeneratorImpl*)statsGenerator; mamaStatsCollector* current; int wasLogged = 0; int logLast = 0; current = (mamaStatsCollector*)list_get_head (impl->mStatsCollectors); /* Stats are logged at WARN so that users don't have to enable NORMAL (or higher) logging, even though they aren't actually warnings...*/ if (impl->mLogStats) { mama_log (MAMA_LOG_LEVEL_WARN, LOG_SEPARATOR); mama_log (MAMA_LOG_LEVEL_WARN, LOG_HEADER); mama_log (MAMA_LOG_LEVEL_WARN, LOG_SEPARATOR); } while (current != NULL) { wasLogged = 0; mamaStatsCollector_populateMsg (*current, impl->mStatMsg, &wasLogged); if (impl->mStatsLogger && mamaStatsCollector_getPublish(*current)) { mamaStatsLogger_addStatMsg (impl->mStatsLogger, impl->mStatMsg); } if (wasLogged) { if (impl->mLogStats && mamaStatsCollector_getLog(*current)) { mama_log (MAMA_LOG_LEVEL_WARN, LOG_SEPARATOR); } } logLast = mamaStatsCollector_getLog(*current); current = (mamaStatsCollector*)list_get_next (impl->mStatsCollectors, current); } if (impl->mStatsLogger) { mamaStatsLogger_sendReport (impl->mStatsLogger); } /* If the last collector didn't give us any stats, still log a separator */ if (!wasLogged && impl->mLogStats && logLast) { mama_log (MAMA_LOG_LEVEL_WARN, LOG_SEPARATOR); } }
void *list_get(list_t list, int index){ if (!list || index < 0) return NULL; if (index == 0) return list_get_head(list); if (index == list->len-1) return list_get_tail(list); struct list_node *p = list->head; for (int i = 0; i < index; i++) p = p->next; return p->data; }
int queue_dequeue(queue_type *queue, void * value) { int rc; if(!queue || !value) return EINVAL; rc = list_get_head(queue->qlist, value); if(rc) return rc; return list_remove_head(queue->qlist); }
int list_insert_at(List *l, int pos, int data) { int i; ListNode *at = list_get_head(l), *node; if (pos==0) return list_push_front(l, data); for (i=0; i<pos; i++) { at = at->next; if (!at && i!=pos-1) return 0; } node = list_create_node(data, at, at->previous); return node!=NULL; }
int graph_command_tna(t_graph_data *rqd, t_server *s, t_world *w) { char response[STR_LIMIT]; t_item *current_team; (void) w; (void) rqd; current_team = list_get_head(s->options.names); while (current_team != NULL) { sprintf(response, "tna %s\n", (char *)(current_team->cont)); cli_answer_to_graph(rqd->user, response); current_team = current_team->next; response[0] = '\0'; } return (0); }
int list_delete_at(List *l, int pos) { int i; ListNode *at = list_get_head(l); if (list_is_empty(l)) return 0; if (pos==0) return list_pop_front(l); for (i=0; i<pos; i++) { at = at->next; if (!at && i!=pos-1) return 0; } list_free_node(at); return 1; }
int list_pop_back(List* l) { int last = l->head, last2 = -1; if (list_is_empty(l)) return 0; while (list_get_node(l, last)->next>=0) { last2 = last; last = list_get_node(l, last)->next; } list_get_node(l, last)->occupied = 0; if (last2>=0) list_get_node(l, last2)->next = -1; else { list_get_head(l)->occupied = 0; l->head = -1; } --l->total; return 1; }
void event_post(const event_id_t id, const event_data_t data) { /* get byte and bit number of the given event in the event mask */ const uint8_t position = id >> 3; const uint8_t mask = 1 << (id & 0x7); const struct event *current; ASSERT((id < EVENT_MAX_AMOUNT)); if (!(subscribed[position] & mask)) { return; /* No subscribers */ } /* Find all subscribers */ for ((current = (const struct event *)list_get_head(&events)); current; current = (const struct event *)list_get_next_element(current)) { if (current->mask[position] & mask) { current->cb(id, data); } } }
int32_t event_unsubscribe(struct event *const event, const event_id_t id) { /* get byte and bit number of the given event in the event mask */ const uint8_t position = id >> 3; const uint8_t mask = 1 << (id & 0x7); const struct event *current; uint8_t i; ASSERT(event && (id < EVENT_MAX_AMOUNT)); if (!(event->mask[position] & mask)) { return ERR_NO_CHANGE; /* Already unsubscribed */ } event->mask[position] &= ~mask; /* Check if there are more subscribers */ for ((current = (const struct event *)list_get_head(&events)); current; current = (const struct event *)list_get_next_element(current)) { if (current->mask[position] & mask) { break; } } if (!current) { subscribed[position] &= ~mask; } /* Remove event from the list. Can be unsave, document it! */ for (i = 0; i < ARRAY_SIZE(event->mask); i++) { if (event->mask[i]) { return ERR_NONE; } } list_delete_element(&events, event); return ERR_NONE; }
BOOL test_pdcp_data_ind(void) { /* * This is the list that pdcp_data_ind() takes to put pdcp_data_ind_header_t * packets after it receives/validates PDUs and preprends them with pdcp_data_ind_header_t * structure. Here, after this list is filled by pdcp_data_ind() we parse/validate * every single element in the list */ list_t test_pdu_indication_list; mem_block_t* test_sdu = NULL; /* * pdcp_data_req() method prepended PDU header in front of DUMMY_BUFFER so * the size should be 12 bytes */ unsigned char test_sdu_size = PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE + DUMMY_BUFFER_SIZE; unsigned int index = 0; /* * Initialize linked list */ list_init(&test_pdu_indication_list, NULL); /* * Ask PDCP to handle a number of data indications */ msg("There are %d PDUs in the list\n", test_pdu_rx_list.nb_elements); /* * Traverse PDU list and pass each one of them to pdcp_data_ind() */ while (list_get_head(&test_pdu_rx_list) != NULL) { msg("\n\nAsking PDCP to receive %d. SDU...\n", 1 + index++); test_sdu = list_remove_head(&test_pdu_rx_list); if (pdcp_data_ind(0, 0, test_sdu_size, test_sdu, &pdcp_array[0], &test_pdu_indication_list) == FALSE) { msg("[TEST] pdcp_data_ind() failed to handle data indication!\n"); return FALSE; } else { msg("[TEST] pdcp_data_ind() succcessfuly handled data indication\n"); } /* * Parse/validate fields of SDU */ msg("[TEST] Starting to dissect SDU created by PDCP...\n"); /* * Get pdcp_data_ind_header_t added by pdcp_data_ind() */ mem_block_t* test_data_ind_header = list_remove_head(&test_pdu_indication_list); if (test_data_ind_header == NULL) { msg("[TEST] Data indication header is not valid!\n"); return FALSE; } else { pdcp_data_ind_header_t* indication_header = (pdcp_data_ind_header_t*)test_data_ind_header->data; /* * Verify that radio bearer ID is correct (0) */ if (indication_header->rb_id == 0) { msg("[TEST] Radio bearer ID is correct\n"); } else { msg("[TEST] Radio bearer ID is not correct! (expected: 0, parsed: %d)\n", indication_header->rb_id); return FALSE; } /* * Verify that SDU size is correct (DUMMY_BUFFER_SIZE) */ if (indication_header->data_size == DUMMY_BUFFER_SIZE + PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE) { msg("[TEST] SDU size is correct\n"); } else { msg("[TEST] SDU size is not correct! (expected: %d, parsed: %d)\n", DUMMY_BUFFER_SIZE, indication_header->data_size); return FALSE; } /* * XXX Verify `indication_header->inst` when you know what it is */ } /* * XXX PDCP PDU header should also be checked here */ /* * Verify that serialised data is the stream we've supplied * * Data comes after `pdcp_data_ind_header_t` and `pdcp_user_plane_data_pdu_header_with_long_sn` */ unsigned char data_index = sizeof(pdcp_data_ind_header_t) + PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE; if (memcmp(DUMMY_BUFFER, (unsigned char*)&(test_data_ind_header->data[data_index]), DUMMY_BUFFER_SIZE) == 0) { msg("[TEST] Data payload of pdcp_data_ind_header_t matches with the stream we sent\n"); } else { msg("[TEST] Data payload of pdcp_data_ind_header_t does not match with the stream we sent!\n"); /* * Print octets of both streams * XXX This could be a method in test_util.h */ print_byte_stream("[TEST] TXed data: ", DUMMY_BUFFER, DUMMY_BUFFER_SIZE); print_byte_stream("[TEST] RXed data: ", (unsigned char*)&(test_data_ind_header->data[data_index]), DUMMY_BUFFER_SIZE); return FALSE; } } return TRUE; }
//----------------------------------------------------------------------------- int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) { //----------------------------------------------------------------------------- mem_block_t *sdu_p = list_get_head (&pdcp_sdu_list); int bytes_wrote = 0; int pdcp_nb_sdu_sent = 0; uint8_t cont = 1; #if defined(LINK_ENB_PDCP_TO_GTPV1U) //MessageDef *message_p = NULL; #endif #if defined(PDCP_USE_NETLINK) && defined(LINUX) int ret = 0; #endif while (sdu_p && cont) { #if ! defined(OAI_EMU) ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; #endif #if defined(LINK_ENB_PDCP_TO_GTPV1U) if (ctxt_pP->enb_flag) { AssertFatal(0, "Now execution should not go here"); LOG_D(PDCP,"Sending to GTPV1U %d bytes\n", ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); gtpv1u_new_data_req( ctxt_pP->module_id, //gtpv1u_data_t *gtpv1u_data_p, ctxt_pP->rnti,//rb_id/maxDRB, TO DO UE ID ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id + 4, &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t)]), ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); list_remove_head (&pdcp_sdu_list); free_mem_block (sdu_p); cont = 1; pdcp_nb_sdu_sent += 1; sdu_p = list_get_head (&pdcp_sdu_list); LOG_D(OTG,"After GTPV1U\n"); continue; // loop again } #endif /* defined(ENABLE_USE_MME) */ #ifdef PDCP_DEBUG LOG_D(PDCP, "PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n", ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); #endif //PDCP_DEBUG cont = 0; if (!pdcp_output_sdu_bytes_to_write) { if (!pdcp_output_header_bytes_to_write) { pdcp_output_header_bytes_to_write = sizeof (pdcp_data_ind_header_t); } #ifdef PDCP_USE_RT_FIFO bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), pdcp_output_header_bytes_to_write); #else #ifdef PDCP_USE_NETLINK #ifdef LINUX memcpy(NLMSG_DATA(nas_nlh_tx), &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), pdcp_output_header_bytes_to_write); nas_nlh_tx->nlmsg_len = pdcp_output_header_bytes_to_write; #endif //LINUX #endif //PDCP_USE_NETLINK bytes_wrote = pdcp_output_header_bytes_to_write; #endif //PDCP_USE_RT_FIFO #ifdef PDCP_DEBUG LOG_D(PDCP, "Frame %d Sent %d Bytes of header to Nas_mesh\n", ctxt_pP->frame, bytes_wrote); #endif //PDCP_DEBUG if (bytes_wrote > 0) { pdcp_output_header_bytes_to_write = pdcp_output_header_bytes_to_write - bytes_wrote; if (!pdcp_output_header_bytes_to_write) { // continue with sdu pdcp_output_sdu_bytes_to_write = ((pdcp_data_ind_header_t *) sdu_p->data)->data_size; #ifdef PDCP_USE_RT_FIFO bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); #else #ifdef PDCP_USE_NETLINK #ifdef LINUX memcpy(NLMSG_DATA(nas_nlh_tx)+sizeof(pdcp_data_ind_header_t), &(sdu_p->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); nas_nlh_tx->nlmsg_len += pdcp_output_sdu_bytes_to_write; ret = sendmsg(nas_sock_fd,&nas_msg_tx,0); if (ret<0) { LOG_D(PDCP, "[PDCP_FIFOS] sendmsg returns %d (errno: %d)\n", ret, errno); MSC_LOG_TX_MESSAGE_FAILED( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, NULL, 0, MSC_AS_TIME_FMT" DATA-IND RNTI %"PRIx16" rb %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); mac_xface->macphy_exit("sendmsg failed for nas_sock_fd\n"); break; } else { MSC_LOG_TX_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, NULL, 0, MSC_AS_TIME_FMT" DATA-IND RNTI %"PRIx16" rb %u size %u", MSC_AS_TIME_ARGS(ctxt_pP), ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); } #endif // LINUX #endif //PDCP_USE_NETLINK bytes_wrote= pdcp_output_sdu_bytes_to_write; #endif // PDCP_USE_RT_FIFO #ifdef PDCP_DEBUG LOG_D(PDCP, "PDCP->IP Frame %d INST %d: Sent %d Bytes of data from rab %d to higher layers\n", ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, bytes_wrote, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); #endif //PDCP_DEBUG if (bytes_wrote > 0) { pdcp_output_sdu_bytes_to_write -= bytes_wrote; if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU // LOG_D(PDCP, "rb sent a sdu qos_sap %d\n", sapiP); LOG_D(PDCP, "[FRAME %05d][xxx][PDCP][MOD xx/xx][RB %u][--- PDCP_DATA_IND / %d Bytes --->][IP][INSTANCE %u][RB %u]\n", ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id, ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); list_remove_head (&pdcp_sdu_list); free_mem_block (sdu_p); cont = 1; pdcp_nb_sdu_sent += 1; sdu_p = list_get_head (&pdcp_sdu_list); } } else { LOG_W(PDCP, "RADIO->IP SEND SDU CONGESTION!\n"); } } else { LOG_W(PDCP, "RADIO->IP SEND SDU CONGESTION!\n"); } } } else { // continue writing sdu #ifdef PDCP_USE_RT_FIFO bytes_wrote = rtf_put (PDCP2PDCP_USE_RT_FIFO, (uint8_t *) (&(sdu_p->data[sizeof (pdcp_data_ind_header_t) + ((pdcp_data_ind_header_t *) sdu_p->data)->data_size - pdcp_output_sdu_bytes_to_write])), pdcp_output_sdu_bytes_to_write); #else // PDCP_USE_RT_FIFO bytes_wrote = pdcp_output_sdu_bytes_to_write; #endif // PDCP_USE_RT_FIFO if (bytes_wrote > 0) { pdcp_output_sdu_bytes_to_write -= bytes_wrote; if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU //PRINT_RB_SEND_OUTPUT_SDU ("[PDCP] RADIO->IP SEND SDU\n"); list_remove_head (&pdcp_sdu_list); free_mem_block (sdu_p); cont = 1; pdcp_nb_sdu_sent += 1; sdu_p = list_get_head (&pdcp_sdu_list); // LOG_D(PDCP, "rb sent a sdu from rab\n"); } } } } #ifdef PDCP_USE_RT_FIFO if ((pdcp_nb_sdu_sent)) { if ((pdcp_2_nas_irq > 0)) { #ifdef PDCP_DEBUG LOG_D(PDCP, "Frame %d : Trigger NAS RX interrupt\n", ctxt_pP->frame); #endif //PDCP_DEBUG rt_pend_linux_srq (pdcp_2_nas_irq); } else { LOG_E(PDCP, "Frame %d: ERROR IF IP STACK WANTED : NOTIF PACKET(S) pdcp_2_nas_irq not initialized : %d\n", ctxt_pP->frame, pdcp_2_nas_irq); } } #endif //PDCP_USE_RT_FIFO return pdcp_nb_sdu_sent; }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- int pdcp_fifo_flush_sdus () { //----------------------------------------------------------------------------- mem_block_t *sdu = list_get_head (&pdcp_sdu_list); int bytes_wrote = 0; int pdcp_nb_sdu_sent = 0; uint8_t cont = 1; int ret; while ((sdu) && (cont)) { #ifdef USER_MODE // asjust the instance id when passing sdu to IP ((pdcp_data_ind_header_t *)(sdu->data))->inst = (((pdcp_data_ind_header_t *)(sdu->data))->inst >= NB_eNB_INST) ? ((pdcp_data_ind_header_t *)(sdu->data))->inst - NB_eNB_INST +oai_emulation.info.nb_enb_local - oai_emulation.info.first_ue_local :// UE ((pdcp_data_ind_header_t *)(sdu->data))->inst - oai_emulation.info.first_ue_local; // ENB #else ((pdcp_data_ind_header_t *)(sdu->data))->inst = 0; #endif #ifdef PDCP_DEBUG msg("[PDCP][INFO] PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n", Mac_rlc_xface->frame, ((pdcp_data_ind_header_t *)(sdu->data))->inst, ((pdcp_data_ind_header_t *)(sdu->data))->data_size, ((pdcp_data_ind_header_t *)(sdu->data))->rb_id); #endif //PDCP_DEBUG cont = 0; if (!pdcp_output_sdu_bytes_to_write) { if (!pdcp_output_header_bytes_to_write) { pdcp_output_header_bytes_to_write = sizeof (pdcp_data_ind_header_t); } #ifndef USER_MODE bytes_wrote = rtf_put (PDCP2NAS_FIFO, &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), pdcp_output_header_bytes_to_write); #else #ifdef NAS_NETLINK #ifdef LINUX memcpy(NLMSG_DATA(nas_nlh), &(((uint8_t *) sdu->data)[sizeof (pdcp_data_ind_header_t) - pdcp_output_header_bytes_to_write]), pdcp_output_header_bytes_to_write); nas_nlh->nlmsg_len = pdcp_output_header_bytes_to_write; #endif //LINUX #endif //NAS_NETLINK bytes_wrote = pdcp_output_header_bytes_to_write; #endif //USER_MODE #ifdef PDCP_DEBUG msg("[PDCP][INFO] TTI %d Sent %d Bytes of header to Nas_mesh\n", Mac_rlc_xface->frame, bytes_wrote); #endif //PDCP_DEBUG if (bytes_wrote > 0) { pdcp_output_header_bytes_to_write = pdcp_output_header_bytes_to_write - bytes_wrote; if (!pdcp_output_header_bytes_to_write) { // continue with sdu pdcp_output_sdu_bytes_to_write = ((pdcp_data_ind_header_t *) sdu->data)->data_size; #ifndef USER_MODE bytes_wrote = rtf_put (PDCP2NAS_FIFO, &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); #else #ifdef NAS_NETLINK #ifdef LINUX memcpy(NLMSG_DATA(nas_nlh)+sizeof(pdcp_data_ind_header_t), &(sdu->data[sizeof (pdcp_data_ind_header_t)]), pdcp_output_sdu_bytes_to_write); nas_nlh->nlmsg_len += pdcp_output_sdu_bytes_to_write; ret = sendmsg(nas_sock_fd,&nas_msg,0); if (ret<0) { msg("[PDCP_FIFOS] sendmsg returns %d\n",ret); perror("error code:"); mac_xface->macphy_exit(""); break; } #endif // LINUX #endif //NAS_NETLINK bytes_wrote= pdcp_output_sdu_bytes_to_write; #endif // USER_MODE #ifdef PDCP_DEBUG msg("[PDCP][INFO] PDCP->IP TTI %d INST %d: Sent %d Bytes of data from rab %d to Nas_mesh\n", Mac_rlc_xface->frame, ((pdcp_data_ind_header_t *)(sdu->data))->inst, bytes_wrote, ((pdcp_data_ind_header_t *)(sdu->data))->rb_id); #endif //PDCP_DEBUG if (bytes_wrote > 0) { pdcp_output_sdu_bytes_to_write -= bytes_wrote; if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU // msg("rb sent a sdu qos_sap %d\n",sapiP); list_remove_head (&pdcp_sdu_list); free_mem_block (sdu); cont = 1; pdcp_nb_sdu_sent += 1; sdu = list_get_head (&pdcp_sdu_list); } } else { msg ("[PDCP] RADIO->IP SEND SDU CONGESTION!\n"); } } else { msg ("[PDCP] RADIO->IP SEND SDU CONGESTION!\n"); } } } else { // continue writing sdu #ifndef USER_MODE bytes_wrote = rtf_put (PDCP2NAS_FIFO, (uint8_t *) (&(sdu->data[sizeof (pdcp_data_ind_header_t) + ((pdcp_data_ind_header_t *) sdu->data)->data_size - pdcp_output_sdu_bytes_to_write])), pdcp_output_sdu_bytes_to_write); #else // USER_MODE bytes_wrote = pdcp_output_sdu_bytes_to_write; #endif // USER_MODE if (bytes_wrote > 0) { pdcp_output_sdu_bytes_to_write -= bytes_wrote; if (!pdcp_output_sdu_bytes_to_write) { // OK finish with this SDU //PRINT_RB_SEND_OUTPUT_SDU ("[PDCP] RADIO->IP SEND SDU\n"); list_remove_head (&pdcp_sdu_list); free_mem_block (sdu); cont = 1; pdcp_nb_sdu_sent += 1; sdu = list_get_head (&pdcp_sdu_list); // msg("rb sent a sdu from rab\n"); } } } } #ifndef USER_MODE if ((pdcp_nb_sdu_sent)) { if ((pdcp_2_nas_irq > 0)) { #ifdef PDCP_DEBUG msg("[PDCP][INFO] TTI %d : Trigger NAS RX interrupt\n", Mac_rlc_xface->frame); #endif //PDCP_DEBUG rt_pend_linux_srq (pdcp_2_nas_irq); } else { msg ("[PDCP] TTI %d: ERROR IF IP STACK WANTED : NOTIF PACKET(S) pdcp_2_nas_irq not initialized : %d\n", Mac_rlc_xface->frame, pdcp_2_nas_irq); } } #endif //USER_MODE return pdcp_nb_sdu_sent; }