📄 sos_module_fetcher.c
字号:
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 inline void handle_overheard_fragment(Message *msg){ fetcher_fragment_t *f; if ( send_state.map == NULL ) { return; } f = (fetcher_fragment_t*)msg->data; if( (send_state.map->key != f->key) ) { return; } DEBUG_PID(KER_FETCHER_PID, "Surpress %d\n", (f->frag_id)); send_state.map->bitmap[(f->frag_id) / 8] &= ~(1 << ((f->frag_id) % 8));}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_cam_lookup(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, send_state.dest);send_fragment_postproc: if(check_map(send_state.map)) { //! no more fragment to send free_send_state_map(); }}static inline int8_t set_num_funcs_in_send_state(sos_cam_t key){ fetcher_cam_t *cam; mod_header_t hdr; cam = (fetcher_cam_t *) ker_cam_lookup(key); if( cam == NULL ) { // We don't have the module, give up return -EINVAL; } if( cam->fetchtype != FETCHTYPE_MODULE ) { // not module return SOS_OK; } // if we are currently fetching the same module if( fst != NULL && (fst->map.key == key) ) { if( (fst->map.bitmap[0] & 0x01) != 0 ) { // number func is not available return -EINVAL; } } // read module header from flash and set it if( ker_codemem_read(cam->cm, KER_FETCHER_PID, &hdr, sizeof(mod_header_t), 0) != SOS_OK ) { return -EINVAL; } send_state.num_funcs = hdr.num_sub_func + hdr.num_prov_func; return SOS_OK;}static int8_t handle_request(Message *msg){ int8_t ret; //! setup a periodic timer to send fragments if(send_state.map == NULL) { fetcher_bitmap_t *b = (fetcher_bitmap_t*) msg->data; ret = set_num_funcs_in_send_state(b->key); if( ret != SOS_OK ) { // cannot find num funcs, give up return SOS_OK; } ret = ker_timer_restart(KER_FETCHER_PID, FETCHER_TRANSMIT_TID, FETCHER_SENDING_FRAGMENT_INTERVAL); if(ret == SOS_OK) { send_state.map = (fetcher_bitmap_t*)ker_msg_take_data(KER_FETCHER_PID, msg); send_state.dest = msg->saddr; DEBUG_PID(KER_FETCHER_PID,"send_state.map = 0x%x send_state.dest = 0x%x\n", (int)send_state.map, send_state.dest); } else { return -ENOMEM; } } else { fetcher_bitmap_t *map = (fetcher_bitmap_t*)msg->data; //! XXX change to broadcast //send_state.dest = BCAST_ADDRESS; DEBUG_PID(KER_FETCHER_PID,"else send_state.dest = %x\n", send_state.dest); //! merge wanted list if((send_state.map->key == map->key)) { uint8_t i; for(i = 0; i < send_state.map->bitmap_size && i < map->bitmap_size; i++) { send_state.map->bitmap[i] |= map->bitmap[i]; } } } if( fst != NULL && (fst->map.key == send_state.map->key) ) { //! send only those we have uint8_t i; for(i = 0; i < send_state.map->bitmap_size; i++ ) { uint8_t tmp; //! this is the fragment that has been requested but we dont have tmp = send_state.map->bitmap[i] & fst->map.bitmap[i]; send_state.map->bitmap[i] &= ~tmp; } } return SOS_OK;}static int8_t handle_data(Message *msg){ fetcher_fragment_t *f; int8_t ret = -EINVAL; fetcher_cam_t *cam; f = (fetcher_fragment_t*)msg->data; DEBUG_PID(KER_FETCHER_PID, "fetcher: get data, key = %d, frag_id = %d\n", f->key, f->frag_id); //msg_print(msg); if(f->key != fst->map.key) { DEBUG_PID(KER_FETCHER_PID,"version mis-match\n"); return SOS_OK; } cam = (fetcher_cam_t *) ker_cam_lookup(f->key); if( cam == NULL ) { // XXX cannot find CAM... // TODO: need to inform upper layer... return -EINVAL; } if( (fst->map.bitmap[(f->frag_id) / 8] & (1 << ((f->frag_id) % 8))) == 0 ) { // we already have the fragment... return SOS_OK; } if((f->frag_id != 0) && ((fst->map.bitmap[0] & 0x01) != 0) && (cam->fetchtype == FETCHTYPE_MODULE)) { // if the first fragment is not available, we drop the packet return SOS_OK; } ret = ker_codemem_write(cam->cm, KER_FETCHER_PID, f->fragment, FETCHER_FRAGMENT_SIZE, (code_addr_t)FETCHER_FRAGMENT_SIZE * f->frag_id); if(ret == SOS_SPLIT) { send_state.fragr = (fetcher_fragment_t*) ker_msg_take_data(KER_FETCHER_PID, msg); f = send_state.fragr; } else if(ret != SOS_OK) { //DEBUG("codemem_write failed\n"); return SOS_OK; } fst->map.bitmap[(f->frag_id) / 8] &= ~(1 << ((f->frag_id) % 8)); check_map_and_post(); return SOS_OK;}static void check_map_and_post(){ if(fst == NULL) { return; } if(check_map(&fst->map)) { fst->retx = 0;#ifdef SOS_SIM /* * We update module version here */ // TODO: figure out the right place... //set_version_to_sim(fst->map.mod_id, fst->map.version);#endif DEBUG_PID(KER_FETCHER_PID, "Request Done!!!\n"); ker_timer_stop(KER_FETCHER_PID, FETCHER_REQUEST_TID); send_fetcher_done(); }}static void start_new_fetch(void){ fst = fst->next; if (fst) { fetcher_cam_t *cam; cam = ker_cam_lookup( fst->map.key ); cam->status = FETCHING_STARTED; ker_timer_start(KER_FETCHER_PID, FETCHER_REQUEST_TID, FETCHER_REQUEST_BACKOFF_SLOT * ((ker_rand() % FETCHER_REQUEST_MAX_SLOT) + 1)); } }static void send_fetcher_done(){ fetcher_cam_t *cam; DEBUG_PID(KER_FETCHER_PID,"Fetcher Done!\n"); if( post_long(fst->requester, KER_FETCHER_PID, MSG_FETCHER_DONE, sizeof(fetcher_state_t), fst, SOS_MSG_RELEASE) != SOS_OK ) { no_mem_retry = true; ker_timer_start(KER_FETCHER_PID, FETCHER_REQUEST_TID, 1024); return; } cam = ker_cam_lookup( fst->map.key ); cam->status = FETCHING_DONE; no_mem_retry = false; start_new_fetch();}//! check whether we have completed the fragment mapstatic bool check_map(fetcher_bitmap_t *m){ uint8_t i; for(i = 0; i < m->bitmap_size; i++) { if(m->bitmap[i] != 0) { return false; } } return true;}#ifdef SOS_DEBUG_FETCHERstatic void print_bitmap(fetcher_bitmap_t *m){ uint8_t i; int16_t delt = 0; char buf[DEBUG_BUFFER_SIZE]; delt = sprintf(buf,"map: "); for(i = 0; i < m->bitmap_size; i++) { delt += sprintf(buf+delt,"0x%x ", m->bitmap[i]); } DEBUG_PID(KER_FETCHER_PID,"%s\n",buf);}#endifint8_t fetcher_init(){ sched_register_kernel_module(&fetcher_module, sos_get_header_address(mod_header), NULL); return SOS_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -