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 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_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_shm_get( KER_FETCHER_PID, 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; }
int8_t ker_timer_start(sos_pid_t pid, uint8_t tid, int32_t interval) { sos_timer_t* tt; //! Start the timer from the timer pool tt = alloc_from_timer_pool(pid, tid); //! If the timer does not exist, then it is already in use or not initialized if (tt == NULL) { DEBUG_PID(TIMER_PID, "ker_timer_start: tt == NULL\n"); return -EINVAL; } // tt->ticks = PROCESSOR_TICKS(interval); tt->ticks = interval; tt->delta = interval; //DEBUG("timer_start(%d) %d %d %d\n", tt->pid, tt->tid, tt->type, tt->ticks); //! insert into delta queue print_all_timers("timer_start_start"); timer_delta_q_insert(tt, true); print_all_timers("timer_start_end"); ker_log( SOS_LOG_TIMER_START, pid, tid ); return SOS_OK; }
int8_t fetcher_request(sos_pid_t req_id, sos_shm_t key, uint16_t size, uint16_t src) { uint8_t bitmap_size; //! size of the bitmap in bytes uint16_t num_fragments; uint8_t i; fetcher_state_t *f; fetcher_cam_t *cam; cam = (fetcher_cam_t *) ker_shm_get( KER_FETCHER_PID, key); if( cam == NULL ) return -EINVAL; //if(fst != NULL) return -EBUSY; DEBUG_PID(KER_FETCHER_PID, "fetcher_request, req_id = %d, size = %d, src = %d\n", req_id, size, src); num_fragments = ((size + (FETCHER_FRAGMENT_SIZE - 1))/ FETCHER_FRAGMENT_SIZE); bitmap_size = (uint8_t)((num_fragments + 7)/ 8); //DEBUG("size = %d\n", sizeof(fetcher_state_t) + bitmap_size); f = ker_malloc(sizeof(fetcher_state_t) + bitmap_size, KER_FETCHER_PID); if(f == NULL) { return -ENOMEM; } //DEBUG("num_fragments = %d, bitmap_zie = %d\n", num_fragments, bitmap_size); f->requester = req_id; f->map.key = key; f->map.bitmap_size = bitmap_size; f->src_addr = src; f->num_funcs = 0; f->next = NULL; f->cm = cam->cm; for(i = 0; i < bitmap_size; i++) { f->map.bitmap[i] = 0xff; } if((num_fragments) % 8) { f->map.bitmap[bitmap_size - 1] = (1 << (num_fragments % 8)) - 1; } print_bitmap(&f->map); //! backoff first!!! f->retx = 0; if(fst != NULL) { fetcher_state_t *tmp = fst; cam->status = FETCHING_QUEUED; while(tmp->next != NULL) { tmp = tmp->next; } tmp->next = f; return SOS_OK; } cam->status = FETCHING_STARTED; fst = f; //! setup timer ker_timer_start(KER_FETCHER_PID, FETCHER_REQUEST_TID, FETCHER_REQUEST_BACKOFF_SLOT * ((ker_rand() % FETCHER_REQUEST_MAX_SLOT) + 1)); //DEBUG("request ret = %d\n", ret); return SOS_OK; }
static 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); }
void pidCrtlCallback(struct lc *lc, struct lc_msg *msg) { struct pidValues *pPid = (struct pidValues *)msg->data; switch (pPid->header.type) { case PID_RATE: DEBUG_PID("Set Rate:\n"); SETKP(&pidRollRate, (float)pPid->KpR/100.0); SETKI(&pidRollRate, (float)pPid->KiR/100.0); SETKD(&pidRollRate, (float)pPid->KdR/100.0); SETKP(&pidPitchRate, (float)pPid->KpP/100.0); SETKI(&pidPitchRate, (float)pPid->KiP/100.0); SETKD(&pidPitchRate, (float)pPid->KdP/100.0); SETKP(&pidYawRate, (float)pPid->KpY/100.0); SETKI(&pidYawRate, (float)pPid->KiY/100.0); SETKD(&pidYawRate, (float)pPid->KdY/100.0); break; case PID_ATT: DEBUG_PID("Set ATT:\n"); SETKP(&pidRoll, (float)pPid->KpR/100.0); SETKI(&pidRoll, (float)pPid->KiR/100.0); SETKD(&pidRoll, (float)pPid->KdR/100.0); SETKP(&pidPitch, (float)pPid->KpP/100.0); SETKI(&pidPitch, (float)pPid->KiP/100.0); SETKD(&pidPitch, (float)pPid->KdP/100.0); SETKP(&pidYaw, (float)pPid->KpY/100.0); SETKI(&pidYaw, (float)pPid->KiY/100.0); SETKD(&pidYaw, (float)pPid->KdY/100.0); break; default: DEBUG_PID("Error unkown type: %d", pPid->header.type); break; } commanderSetRPYType( (RPYType) IS_BIT_SET(pPid->header.mode, PID_ATT_MODE_R), (RPYType) IS_BIT_SET(pPid->header.mode, PID_ATT_MODE_P), (RPYType) IS_BIT_SET(pPid->header.mode, PID_ATT_MODE_Y) ); lc_sendAct(lc); }
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 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_shm_get( KER_FETCHER_PID, fst->map.key ); cam->status = FETCHING_DONE; no_mem_retry = false; start_new_fetch(); }
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 int8_t request_new_module(sos_cam_t key, loader_cam_t *cam, uint8_t size, uint16_t saddr, uint8_t type) { cam->code_size = size; cam->fetcher.fetchtype = type; cam->fetcher.cm = ker_codemem_alloc( size * LOADER_SIZE_MULTIPLIER, CODEMEM_TYPE_EXECUTABLE); DEBUG_PID( KER_DFT_LOADER_PID, "request new module with size = %d\n", size * LOADER_SIZE_MULTIPLIER); if(cam->fetcher.cm == CODEMEM_INVALID) { return -ENOMEM; } if( fetcher_request( KER_DFT_LOADER_PID, key, (uint16_t)size * LOADER_SIZE_MULTIPLIER, saddr ) != SOS_OK ) { ker_codemem_free( cam->fetcher.cm ); return -ENOMEM; } block_protocol(); return SOS_OK; }
static void start_experiment(uint16_t size) { sos_cam_t key; loader_cam_t *cam; codemem_t cm; uint8_t buf[2]; buf[0] = 128; buf[1] = 1; DEBUG_PID(KER_DFT_LOADER_PID, "start experiment: size = %d\n", size); cm = ker_codemem_alloc( size, CODEMEM_TYPE_EXECUTABLE); ker_codemem_write(cm, KER_DFT_LOADER_PID, buf, 2, 0); cam = ker_malloc(sizeof(loader_cam_t), KER_DFT_LOADER_PID); st.version_data->pam_ver[0]++; st.version_data->pam_size[0] = (size + (LOADER_SIZE_MULTIPLIER - 1)) / LOADER_SIZE_MULTIPLIER; st.version_data->version ++; key = ker_cam_key( KER_DFT_LOADER_PID, 0 ); cam->fetcher.fetchtype = FETCHTYPE_DATA; cam->fetcher.cm = cm; ker_cam_add(key, cam); restartInterval(0); }
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; }
static int8_t handle_fetcher_done( Message *msg ) { fetcher_state_t *f = (fetcher_state_t*) msg->data; if( is_fetcher_succeed( f ) == true ) { //mod_header_ptr p; loader_cam_t *cam; fetcher_commit(f, true); st.blocked = 0; restartInterval( 0 ); cam = ker_cam_lookup( f->map.key ); if( cam->fetcher.fetchtype == FETCHTYPE_DATA) { uint8_t buf[2]; ker_codemem_read( cam->fetcher.cm, KER_DFT_LOADER_PID, buf, 2, 0); post_short(buf[0], KER_DFT_LOADER_PID, MSG_LOADER_DATA_AVAILABLE, buf[1], cam->fetcher.cm, 0); DEBUG_PID(KER_DFT_LOADER_PID, "Data Ready\n" ); #ifdef LOADER_NET_EXPERIMENT ker_led(LED_GREEN_TOGGLE); #endif } else { uint8_t mcu_type; #ifndef SOS_SIM uint8_t plat_type; #endif mod_header_ptr p; #ifdef MINIELF_LOADER // Link and load the module here melf_load_module(cam->fetcher.cm); #endif//MINIELF_LOADER // Get the address of the module header p = ker_codemem_get_header_address( cam->fetcher.cm ); // get processor type and platform type mcu_type = sos_read_header_byte(p, offsetof( mod_header_t, processor_type )); #ifdef SOS_SIM if( (mcu_type == MCU_TYPE) ) // In simulation, we don't check for platform #else plat_type = sos_read_header_byte(p, offsetof( mod_header_t, platform_type )); if( (mcu_type == MCU_TYPE) && ( plat_type == HW_TYPE || plat_type == PLATFORM_ANY) ) #endif { /* * If MCU is matched, this means we are using the same * instruction set. * And if this module is for this *specific* platform or * simply for all platform with the same MCU */ // mark module executable ker_codemem_mark_executable( cam->fetcher.cm ); if (cam->version & 0x80) { #ifdef SOS_SFI #ifdef MINIELF_LOADER sfi_modtable_register(cam->fetcher.cm); if (SOS_OK == ker_verify_module(cam->fetcher.cm)){ sfi_modtable_flash(p); ker_register_module(p); } else sfi_exception(KER_VERIFY_FAIL_EXCEPTION); #else uint16_t init_offset, code_size, handler_addr; uint32_t handler_byte_addr, module_start_byte_addr; uint16_t handler_sfi_addr; handler_sfi_addr = sos_read_header_ptr(p, offsetof(mod_header_t, module_handler)); handler_addr = sfi_modtable_get_real_addr(handler_sfi_addr); handler_byte_addr = (handler_addr * 2); module_start_byte_addr = (p * 2); init_offset = (uint16_t)(handler_byte_addr - module_start_byte_addr); code_size = cam->code_size * LOADER_SIZE_MULTIPLIER; if (SOS_OK == ker_verify_module(cam->fetcher.cm, init_offset, code_size)){ sfi_modtable_flash(p); ker_register_module(p); } else sfi_exception(KER_VERIFY_FAIL_EXCEPTION); #endif //MINIELF_LOADER #else ker_register_module(p); #endif //SOS_SFI } } } process_version_data( st.version_data, st.recent_neighbor); } else { DEBUG_PID( KER_DFT_LOADER_PID, "Fetch failed!, request %d\n", st.recent_neighbor); f = (fetcher_state_t*) ker_msg_take_data(KER_DFT_LOADER_PID, msg); fetcher_restart( f, st.recent_neighbor ); } return SOS_OK; }