static void recv_handler(void *dummy) { struct sk_buff *skb; while ((skb = skb_dequeue(&recv_queue)) != 0) { __u16 appl = CAPIMSG_APPID(skb->data); struct avmb1_ncci *np; if (!VALID_APPLID(appl)) { printk(KERN_ERR "b1capi: recv_handler: applid %d ? (%s)\n", appl, capi_message2str(skb->data)); kfree_skb(skb); continue; } if (APPL(appl)->signal == 0) { printk(KERN_ERR "b1capi: recv_handler: applid %d has no signal function\n", appl); kfree_skb(skb); continue; } if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3 && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF && (np = find_ncci(APPL(appl), CAPIMSG_NCCI(skb->data))) != 0 && mq_dequeue(np, CAPIMSG_MSGID(skb->data)) == 0) { printk(KERN_ERR "b1capi: msgid %hu ncci 0x%x not on queue\n", CAPIMSG_MSGID(skb->data), np->ncci); } skb_queue_tail(&APPL(appl)->recv_queue, skb); (APPL(appl)->signal) (APPL(appl)->applid, APPL(appl)->param); } }
//Queue deallocators //called at cleanup void mq_free(message_queue* mq) { assert(mq != NULL); MessageEnvelope* env = NULL; while (!mq_is_empty(mq)) { env = mq_dequeue(mq); assert(env != NULL); free(env); } free(mq); }
/*===========================================================================* * blockdriver_receive_mq * *===========================================================================*/ PUBLIC int blockdriver_receive_mq(message *m_ptr, int *status_ptr) { /* receive() interface for drivers with message queueing. */ /* Any queued messages? */ if (mq_dequeue(SINGLE_THREAD, m_ptr, status_ptr)) return OK; /* Fall back to standard receive() interface otherwise. */ return driver_receive(ANY, m_ptr, status_ptr); }
/* * Deallocate a ppp unit. Must be called at splsoftnet or higher. */ void pppdealloc(struct ppp_softc *sc) { struct ppp_pkt *pkt; struct mbuf *m; splsoftassert(IPL_SOFTNET); if_down(&sc->sc_if); sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING); sc->sc_devp = NULL; sc->sc_xfer = 0; while ((pkt = ppp_pkt_dequeue(&sc->sc_rawq)) != NULL) ppp_pkt_free(pkt); while ((m = mq_dequeue(&sc->sc_inq)) != NULL) m_freem(m); for (;;) { IF_DEQUEUE(&sc->sc_fastq, m); if (m == NULL) break; m_freem(m); } while ((m = sc->sc_npqueue) != NULL) { sc->sc_npqueue = m->m_nextpkt; m_freem(m); } m_freem(sc->sc_togo); sc->sc_togo = NULL; #ifdef PPP_COMPRESS ppp_ccp_closed(sc); sc->sc_xc_state = NULL; sc->sc_rc_state = NULL; #endif /* PPP_COMPRESS */ #if NBPFILTER > 0 if (sc->sc_pass_filt.bf_insns != 0) { free(sc->sc_pass_filt.bf_insns, M_DEVBUF, 0); sc->sc_pass_filt.bf_insns = 0; sc->sc_pass_filt.bf_len = 0; } if (sc->sc_active_filt.bf_insns != 0) { free(sc->sc_active_filt.bf_insns, M_DEVBUF, 0); sc->sc_active_filt.bf_insns = 0; sc->sc_active_filt.bf_len = 0; } #endif #ifdef VJC if (sc->sc_comp != 0) { free(sc->sc_comp, M_DEVBUF, 0); sc->sc_comp = 0; } #endif }
static void handle_senddone( void ) { uint8_t succ; Message *m; while( 1 ) { m = mq_dequeue( &senddoneq ); if( m == NULL ) { break; } if( m->flag & SOS_MSG_SEND_FAIL ) { succ = 0; } else { succ = 1; } m->flag &= ~SOS_MSG_SEND_FAIL; msg_send_senddone( m, succ, RADIO_PID ); } senddone_callback_requested = false; }
static void do_dispatch() { Message *e; // Current message being dispatched sos_module_t *handle; // Pointer to the control block of the destination module Message *inner_msg = NULL; // Message sent as a payload in MSG_PKT_SENDDONE sos_pid_t senddone_dst_pid = NULL_PID; // Destination module ID for the MSG_PKT_SENDDONE uint8_t senddone_flag = SOS_MSG_SEND_FAIL; // Status information for the MSG_PKT_SENDDONE SOS_MEASUREMENT_DEQUEUE_START(); e = mq_dequeue(&schedpq); SOS_MEASUREMENT_DEQUEUE_END(); handle = ker_get_module(e->did); // Destination module might muck around with the // type field. So we check type before dispatch if(e->type == MSG_PKT_SENDDONE) { inner_msg = (Message*)(e->data); } // Check for reliable message delivery if(flag_msg_reliable(e->flag)) { senddone_dst_pid = e->sid; } // Deliver message to the monitor // Ram - Modules might access kernel domain here monitor_deliver_incoming_msg_to_monitor(e); if(handle != NULL) { if(sched_message_filtered(handle, e) == false) { int8_t ret; msg_handler_t handler; void *handler_state; DEBUG("###################################################################\n"); DEBUG("MESSAGE FROM %d TO %d OF TYPE %d\n", e->sid, e->did, e->type); DEBUG("###################################################################\n"); // Get the function pointer to the message handler handler = (msg_handler_t)sos_read_header_ptr(handle->header, offsetof(mod_header_t, module_handler)); // Get the pointer to the module state handler_state = handle->handler_state; // Change ownership if the release flag is set // Ram - How to deal with memory blocks that are not released ? if(flag_msg_release(e->flag)){ ker_change_own(e->data, e->did); } DEBUG("RUNNING HANDLER OF MODULE %d \n", handle->pid); // curr_pid = handle->pid; ker_log( SOS_LOG_HANDLE_MSG, curr_pid, e->type ); ker_push_current_pid(handle->pid); ret = handler(handler_state, e); ker_pop_current_pid(); ker_log( SOS_LOG_HANDLE_MSG_END, curr_pid, e->type ); DEBUG("FINISHED HANDLER OF MODULE %d \n", handle->pid); if (ret == SOS_OK) senddone_flag = 0; } } else { //XXX no error notification for now. DEBUG("Scheduler: Unable to find module\n"); } if(inner_msg != NULL) { //! this is SENDDONE message msg_dispose(inner_msg); msg_dispose(e); } else { if(senddone_dst_pid != NULL_PID) { if(post_long(senddone_dst_pid, KER_SCHED_PID, MSG_PKT_SENDDONE, sizeof(Message), e, senddone_flag) < 0) { msg_dispose(e); } } else { //! return message back to the pool msg_dispose(e); } } }
/************************************************************************* * implement backoff mechanism for Colliosn Avoidance * *************************************************************************/ void backoff_timeout() { // Dimitrios HAS_CRITICAL_SECTION; uint8_t tx_failed=0; ENTER_CRITICAL_SECTION(); if( isQueueEmpty() ) { LEAVE_CRITICAL_SECTION(); return; } if(valid_msg==0) { vmac_msg = NULL; vmac_msg = mq_dequeue(&vmac_pq); // dequeue packet from mq if(vmac_msg) valid_msg=1; } if(valid_msg==1) { if( Radio_Check_CCA() ) { if(radio_msg_send(vmac_msg)) { valid_msg=0; msg_send_senddone(vmac_msg, 1, RADIO_PID); ENTER_CRITICAL_SECTION(); resetRetries(); //set retry_count 0 } else { tx_failed=1; } } else { tx_failed=1; } } // Message transmission did not work! if(tx_failed==1) { if( getRetries() < (uint8_t)MAX_RETRIES ) { incRetries(); //increase retry_count } else { if(vmac_msg) { valid_msg=0; msg_send_senddone(vmac_msg, 0, RADIO_PID); //to release the memory for this msg ENTER_CRITICAL_SECTION(); resetRetries(); //set retry_count 0 } } } uint16_t sleeptime = MacBackoff_congestionBackoff(retry_count); ker_timer_restart(RADIO_PID, WAKEUP_TIMER_TID, sleeptime); // setup new backoff timer LEAVE_CRITICAL_SECTION(); }