static inline void handle_request_timeout() { if(fst == NULL) { return; } //sos_assert(fst != NULL); //DEBUG("handle request timeout, retx = %d\n", fst->retx); fst->retx++; if(fst->retx <= FETCHER_REQUEST_MAX_RETX) { fetcher_bitmap_t *m; uint8_t size = sizeof(fetcher_bitmap_t) + fst->map.bitmap_size; DEBUG_PID(KER_FETCHER_PID,"send request to %d\n", fst->src_addr); print_bitmap(&fst->map); m = (fetcher_bitmap_t *) ker_malloc( size, KER_FETCHER_PID); if( m != NULL ) { memcpy(m, &(fst->map), size); m->key = ehtons( m->key ); post_auto(KER_FETCHER_PID, KER_FETCHER_PID, MSG_FETCHER_REQUEST, size, m, SOS_MSG_RELEASE, fst->src_addr); } restart_request_timer(); } else { DEBUG_PID(KER_FETCHER_PID, "request failed!!!\n"); //codemem_close(&fst->cm, false); send_fetcher_done(); } }
static int8_t handle_loader_ls_on_node( Message *msg ) { msg_ls_reply_t *reply; uint8_t i; reply = (msg_ls_reply_t *) ker_malloc( sizeof( msg_ls_reply_t ), KER_DFT_LOADER_PID ); if( reply == NULL ) return -ENOMEM; for( i = 0; i < NUM_LOADER_PARAMS_ENTRIES; i ++ ) { sos_cam_t key = ker_cam_key( KER_DFT_LOADER_PID, i ); loader_cam_t *cam; uint8_t buf[2]; cam = ker_cam_lookup( key ); if( cam != NULL && cam->fetcher.status == FETCHING_DONE && (ker_codemem_read( cam->fetcher.cm, KER_DFT_LOADER_PID, buf, 2, 0) == SOS_OK)) { DEBUG_PID( KER_DFT_LOADER_PID, "Data(%d) = %d %d\n", i, buf[0], buf[1]); reply->pam_dst_pid[ i ] = buf[0]; reply->pam_dst_subpid[ i ] = buf[1]; } else { DEBUG_PID( KER_DFT_LOADER_PID, "Data(%d) = NULL\n", i); /* if( cam != NULL && cam->fetcher.status == FETCHING_DONE) { DEBUG_PID( KER_DFT_LOADER_PID, "ker_codemem_read failed...\n"); } */ reply->pam_dst_pid[ i ] = NULL_PID; reply->pam_dst_subpid[ i ] = 0; } } for( i = 0; i < NUM_LOADER_MODULE_ENTRIES; i ++ ) { sos_cam_t key = ker_cam_key( KER_DFT_LOADER_PID, NUM_LOADER_PARAMS_ENTRIES + i ); loader_cam_t *cam; cam = ker_cam_lookup( key ); if( cam != NULL && cam->fetcher.status == FETCHING_DONE ) { mod_header_ptr p; sos_code_id_t cid; // Get the address of the module header p = ker_codemem_get_header_address( cam->fetcher.cm ); cid = sos_read_header_word( p, offsetof(mod_header_t, code_id)); // warning: already netowrk order... reply->code_id[ i ] = cid; } else { reply->code_id[ i ] = 0; } } post_auto( KER_DFT_LOADER_PID, KER_DFT_LOADER_PID, MSG_LOADER_LS_REPLY, sizeof( msg_ls_reply_t ), reply, SOS_MSG_RELEASE, msg->saddr); return SOS_OK; }
static inline void send_fragment() { uint16_t frag_id; uint8_t i, j; uint8_t mask = 1; uint8_t ret; fetcher_fragment_t *out_pkt; fetcher_cam_t *cam; if ( send_state.map == NULL ) { ker_timer_stop(KER_FETCHER_PID, FETCHER_TRANSMIT_TID); return; } cam = (fetcher_cam_t *) ker_shm_get( KER_FETCHER_PID, send_state.map->key); if ( cam == NULL ) { // file got deleted. give up! free_send_state_map(); return; } if ( send_state.frag != NULL) { //! timer fires faster than data reading. Highly unlikely... //! but we still handle it. return; } //! search map and find one fragment to send for(i = 0; i < send_state.map->bitmap_size; i++) { //! for each byte if(send_state.map->bitmap[i] != 0) { break; } } if(i == send_state.map->bitmap_size) { /* * Did not find any block... */ free_send_state_map(); return; } //sos_assert(i < send_state.map->bitmap_size); frag_id = i * 8; mask = 1; for(j = 0; j < 8; j++, mask = mask << 1) { if(mask & (send_state.map->bitmap[i])) { send_state.map->bitmap[i] &= ~(mask); break; } } //sos_assert(j < 8); frag_id += j; print_bitmap(send_state.map); out_pkt = (fetcher_fragment_t*)ker_malloc(sizeof(fetcher_fragment_t), KER_FETCHER_PID); if(out_pkt == NULL){ DEBUG_PID(KER_FETCHER_PID,"malloc fetcher_fragment_t failed\n"); goto send_fragment_postproc; } out_pkt->frag_id = ehtons(frag_id); out_pkt->key = ehtons(send_state.map->key); ret = ker_codemem_read(cam->cm, KER_FETCHER_PID, out_pkt->fragment, FETCHER_FRAGMENT_SIZE, frag_id * (code_addr_t)FETCHER_FRAGMENT_SIZE); if(ret == SOS_SPLIT) { send_state.frag = out_pkt; } else if(ret != SOS_OK){ DEBUG_PID(KER_FETCHER_PID, "codemem_read failed\n"); ker_free(out_pkt); goto send_fragment_postproc; } //DEBUG("out_pkt has addr %x\n", (int)out_pkt); DEBUG_PID(KER_FETCHER_PID, "send_fragment: frag_id = %d to %d\n", frag_id, send_state.dest); ret = post_auto(KER_FETCHER_PID, KER_FETCHER_PID, MSG_FETCHER_FRAGMENT, sizeof(fetcher_fragment_t), out_pkt, SOS_MSG_RELEASE | SOS_MSG_RELIABLE, send_state.dest); if( ret == SOS_OK ) { send_state.num_msg_in_queue++; } send_fragment_postproc: if(check_map(send_state.map)) { //! no more fragment to send free_send_state_map(); } }
static int8_t fetcher_handler(void *state, Message *msg) { switch (msg->type) { case MSG_FETCHER_FRAGMENT: { fetcher_fragment_t *f; f = (fetcher_fragment_t*)msg->data; f->key = entohs( f->key ); f->frag_id = entohs(f->frag_id); DEBUG_PID(KER_FETCHER_PID,"MSG_FETCHER_FRAGMENT:\n"); handle_overheard_fragment(msg); if(fst == NULL) { DEBUG_PID(KER_FETCHER_PID, "NO Request!!!\n"); return SOS_OK; //!< no request } //DEBUG_PID(KER_FETCHER_PID,"calling restart_request_timer()\n"); restart_request_timer(); fst->retx = 0; //DEBUG_PID(KER_FETCHER_PID,"calling handle_data()\n"); return handle_data(msg); } case MSG_FETCHER_REQUEST: { fetcher_bitmap_t *bmap = (fetcher_bitmap_t *) msg->data; bmap->key = entohs( bmap->key ); //! received request from neighbors DEBUG("handling request to %d from %d\n", msg->daddr, msg->saddr); if(msg->daddr == ker_id()) { return handle_request(msg); } if(fst == NULL) return SOS_OK; //!< no request restart_request_timer(); fst->retx = 0; return SOS_OK; } case MSG_TIMER_TIMEOUT: { MsgParam *params = (MsgParam*)(msg->data); if(params->byte == FETCHER_REQUEST_TID) { //DEBUG("request timeout\n"); if( no_mem_retry ) { send_fetcher_done(); return SOS_OK; } handle_request_timeout(); } else if(params->byte == FETCHER_TRANSMIT_TID) { //DEBUG("send fragment timeout\n"); if( send_state.num_msg_in_queue < FETCHER_MAX_MSG_IN_QUEUE ) { send_fragment(); } } return SOS_OK; } case MSG_PKT_SENDDONE: { if( send_state.num_msg_in_queue > 0 ) { send_state.num_msg_in_queue--; } return SOS_OK; } #ifdef SOS_HAS_EXFLASH case MSG_EXFLASH_WRITEDONE: { ker_free(send_state.fragr); send_state.fragr = NULL; check_map_and_post(); return SOS_OK; } case MSG_EXFLASH_READDONE: { post_auto(KER_FETCHER_PID, KER_FETCHER_PID, MSG_FETCHER_FRAGMENT, sizeof(fetcher_fragment_t), send_state.frag, SOS_MSG_RELEASE, send_state.dest); send_state.frag = NULL; return SOS_OK; } #endif case MSG_INIT: { send_state.map = NULL; send_state.frag = NULL; send_state.fragr = NULL; send_state.num_msg_in_queue = 0; ker_msg_change_rules(KER_FETCHER_PID, SOS_MSG_RULES_PROMISCUOUS); ker_permanent_timer_init(&(send_state.timer), KER_FETCHER_PID, FETCHER_TRANSMIT_TID, TIMER_REPEAT); ker_timer_init(KER_FETCHER_PID, FETCHER_REQUEST_TID, TIMER_ONE_SHOT); return SOS_OK; } } return -EINVAL; }