int8_t bmac_tx_pkt(char *buf, uint8_t len) { uint32_t mask; if(tx_data_ready==1) return NRK_ERROR; // If reserve exists check it #ifdef NRK_MAX_RESERVES if(tx_reserve!=-1) { if( nrk_reserve_consume(tx_reserve)==NRK_ERROR ) { return NRK_ERROR; } } #endif nrk_signal_register(bmac_tx_pkt_done_signal); tx_data_ready=1; bmac_rfTxInfo.pPayload=buf; bmac_rfTxInfo.length=len; #ifdef DEBUG printf("Waiting for tx done signal\r\n"); #endif mask=nrk_event_wait (SIG(bmac_tx_pkt_done_signal)); if(mask==0) printf("BMAC TX: Error calling event wait\r\n"); if((mask&SIG(bmac_tx_pkt_done_signal))==0) printf("BMAC TX: Woke up on wrong signal\r\n"); if(pkt_got_ack) {//printf("NRK OK \r\n"); return NRK_OK;} return NRK_ERROR; }
void rx_task() { char c; nrk_sig_t uart_rx_signal; nrk_sig_mask_t sm; printf( "My node's address is %d\r\n",NODE_ADDR ); printf( "rx_task PID=%d\r\n",nrk_get_pid()); // Get the signal for UART RX uart_rx_signal=nrk_uart_rx_signal_get(); // Register your task to wakeup on RX Data if(uart_rx_signal==NRK_ERROR) nrk_kprintf( PSTR("Get Signal ERROR!\r\n") ); nrk_signal_register(uart_rx_signal); while(1) { // Wait for UART signal while(nrk_uart_data_ready(NRK_DEFAULT_UART)!=0) { // Read Character c=getchar(); printf( "%c",c); if(c=='x') nrk_led_set(GREEN_LED); else nrk_led_clr(GREEN_LED); } sm=nrk_event_wait(SIG(uart_rx_signal)); if(sm != SIG(uart_rx_signal)) nrk_kprintf( PSTR("RX signal error") ); nrk_kprintf( PSTR("\r\ngot uart data: ") ); } }
int8_t isa_wait_until_rx_or_tx () { nrk_signal_register(isa_rx_pkt_signal); nrk_signal_register(isa_tx_done_signal); nrk_event_wait (SIG(isa_rx_pkt_signal) | SIG(isa_tx_done_signal)); return NRK_OK; }
int8_t tdma_send (tdma_info * fd, uint8_t * buf, uint8_t len, uint8_t flags) { uint32_t mask; uint8_t i; if (tx_data_ready == 1) return NRK_ERROR; if (len == 0) return NRK_ERROR; if (buf == NULL) return NRK_ERROR; if (fd == NULL) return NRK_ERROR; // If reserve exists check it #ifdef NRK_MAX_RESERVES if (tx_reserve != -1) { if (nrk_reserve_consume (tx_reserve) == NRK_ERROR) { return NRK_ERROR; } } #endif if (flags == TDMA_BLOCKING) nrk_signal_register (tdma_tx_pkt_done_signal); tx_data_ready = 1; tdma_rfTxInfo.pPayload = tdma_tx_buf; // Setup the header data tdma_rfTxInfo.pPayload[TDMA_SLOT_HIGH] = (fd->slot >> 8) & 0xff; tdma_rfTxInfo.pPayload[TDMA_SLOT_LOW] = (fd->slot & 0xff); tdma_rfTxInfo.pPayload[TDMA_DST_HIGH] = (fd->dst >> 8) & 0xff; tdma_rfTxInfo.pPayload[TDMA_DST_LOW] = (fd->dst & 0xff); tdma_rfTxInfo.pPayload[TDMA_SRC_HIGH] = (fd->src >> 8) & 0xff; tdma_rfTxInfo.pPayload[TDMA_SRC_LOW] = (tdma_my_mac & 0xff); tdma_rfTxInfo.pPayload[TDMA_SEQ_NUM_HIGH] = (tdma_my_mac >> 8) & 0xff; tdma_rfTxInfo.pPayload[TDMA_SEQ_NUM_LOW] = (fd->seq_num & 0xff); tdma_rfTxInfo.pPayload[TDMA_CYCLE_SIZE_HIGH] = (fd->cycle_size >> 8) & 0xff; tdma_rfTxInfo.pPayload[TDMA_CYCLE_SIZE_LOW] = (fd->cycle_size & 0xff); // Copy the user payload to the back of the header for (i = 0; i < len; i++) tdma_rfTxInfo.pPayload[i + TDMA_PCF_HEADER] = buf[i]; // Set packet length with header tdma_rfTxInfo.length = len + TDMA_PCF_HEADER; #ifdef DEBUG nrk_kprintf (PSTR ("Waiting for tx done signal\r\n")); #endif if (flags == TDMA_BLOCKING) { mask = nrk_event_wait (SIG (tdma_tx_pkt_done_signal)); if (mask == 0) nrk_kprintf (PSTR ("TDMA TX: Error calling event wait\r\n")); if ((mask & SIG (tdma_tx_pkt_done_signal)) == 0) nrk_kprintf (PSTR ("TDMA TX: Woke up on wrong signal\r\n")); return NRK_OK; } return NRK_OK; }
void bmac_nw_task () { int8_t v; int8_t e; uint8_t backoff; nrk_sig_mask_t event; while(bmac_started()==0) nrk_wait_until_next_period(); //register the signal after bmac_init has been called v=nrk_signal_register(bmac_enable_signal); if(v==NRK_ERROR) nrk_kprintf( PSTR("Failed to register signal\r\n")); backoff=0; while (1) { #ifdef NRK_SW_WDT #ifdef BMAC_SW_WDT_ID nrk_sw_wdt_update(BMAC_SW_WDT_ID); #endif #endif if(is_enabled ) { v=1; if(rx_buf_empty==1) v=_bmac_channel_check(); // If the buffer is full, signal the receiving task again. else e=nrk_event_signal (bmac_rx_pkt_signal); // bmac_channel check turns on radio, don't turn off if // data is coming. if(v==0) { if(_bmac_rx()==1) { e=nrk_event_signal (bmac_rx_pkt_signal); //if(e==NRK_ERROR) { // nrk_kprintf( PSTR("bmac rx pkt signal failed\r\n")); // printf( "errno: %u \r\n",nrk_errno_get() ); //} } //else nrk_kprintf( PSTR("Pkt failed, buf could be corrupt\r\n" )); } if(/*rx_buf_empty==1 &&*/ tx_data_ready==1) { rf_rx_off(); _bmac_tx(); } //do { nrk_wait(_bmac_check_period); // if(rx_buf_empty!=1) nrk_event_signal (bmac_rx_pkt_signal); //} while(rx_buf_empty!=1); } else { event=0; do { v=nrk_signal_register(bmac_enable_signal); event=nrk_event_wait (SIG(bmac_enable_signal)); } while((event & SIG(bmac_enable_signal))==0); } //nrk_wait_until_next_period(); } }
void bmac_nw_task() { int8_t v; int8_t e; uint8_t backoff; nrk_sig_mask_t event; while(bmac_started() == 0) { nrk_wait_until_next_period(); } while(1) { if(is_enabled) { v = 1; rf_rx_on(); if(rx_buf_empty) { v = _bmac_channel_check(); } else { e = nrk_event_signal(bmac_rx_pkt_signal); // Mb // Should signal user task here as a "reminder" } if(v == 0) { // Channel detected as busy, attept to Rx _bmac_rx(); // Should signal user task here to notify of Rx } else if(tx_data_ready) { // Only try to Tx if the channel is free rf_rx_off(); // Mb _bmac_tx(); } //rf_rx_off(); // Mb nrk_wait(_bmac_check_period); } else { event =0; do { v = nrk_signal_register(bmac_enable_signal); event = nrk_event_wait(SIG(bmac_enable_signal)); } while((event & SIG(bmac_enable_signal))==0); } } }
int8_t nrk_signal_register(int8_t sig_id) { // Make sure the signal was created... if(SIG(sig_id) & _nrk_signal_list ) { nrk_cur_task_TCB->registered_signal_mask|=SIG(sig_id); return NRK_OK; } return NRK_ERROR; }
int8_t bmac_wait_until_rx_pkt() { nrk_sig_mask_t event; if(bmac_rx_pkt_ready()==1) return NRK_OK; nrk_signal_register(bmac_rx_pkt_signal); event=nrk_event_wait (SIG(bmac_rx_pkt_signal)); // Check if it was a time out instead of packet RX signal if((event & SIG(bmac_rx_pkt_signal)) == 0 ) return NRK_ERROR; else return NRK_OK; }
void tx_task () { uint8_t j, i, val, len, cnt; volatile uint8_t start; uint16_t ticks,ticks_min,ticks_max; uint16_t iterations; uint16_t nrk_max_sleep_wakeup_time; nrk_sig_t tx_done_signal; nrk_sig_mask_t ret; iterations=0; ticks_min=-1; ticks_max=0; tx_data_ok=0; // Wait until the tx_task starts up bmac // This should be called by all tasks using bmac that // do not call bmac_init()... while (!bmac_started ()) nrk_wait_until_next_period (); // Get and register the tx_done_signal if you want to // do non-blocking transmits tx_done_signal = bmac_get_tx_done_signal (); nrk_signal_register (tx_done_signal); cnt = 0; while (1) { // Build a TX packet sprintf (tx_buf, "This is a test %d", cnt); cnt++; // For blocking transmits, use the following function call. // For this there is no need to register // val=bmac_tx_packet(tx_buf, strlen(tx_buf)); // This function shows how to transmit packets in a // non-blocking manner val = bmac_tx_pkt_nonblocking(tx_buf, strlen (tx_buf)); // This functions waits on the tx_done_signal ret = nrk_event_wait (SIG(tx_done_signal)); // Just check to be sure signal is okay if(ret & SIG(tx_done_signal) == 0 ) nrk_kprintf (PSTR ("TX done signal error\r\n")); else tx_data_ok=1; // Task gets control again after TX complete //nrk_kprintf (PSTR ("Tx task sent data!\r\n")); nrk_wait_until_next_period (); } }
int8_t tdma_recv (tdma_info * fd, uint8_t * buf, uint8_t * len, uint8_t flags) { nrk_sig_mask_t event; uint8_t i; if (flags == TDMA_BLOCKING) { if (tdma_rx_buf_empty == 1) { nrk_signal_register (tdma_rx_pkt_signal); event = nrk_event_wait (SIG (tdma_rx_pkt_signal)); } } else if (tdma_rx_buf_empty == 1) return NRK_ERROR; if (tdma_rfRxInfo.length < TDMA_PCF_HEADER) return NRK_ERROR; // Set the length *len = (uint8_t) (tdma_rfRxInfo.length - TDMA_PCF_HEADER); // Copy the payload data for (i = 0; i < *len; i++) buf[i] = tdma_rfRxInfo.pPayload[i + TDMA_PCF_HEADER]; // Fill the information struct fd->rssi = tdma_rfRxInfo.rssi; fd->src = ((uint16_t) tdma_rfRxInfo.pPayload[TDMA_SRC_HIGH] << 8) | tdma_rfRxInfo. pPayload[TDMA_SRC_LOW]; fd->dst = ((uint16_t) tdma_rfRxInfo.pPayload[TDMA_DST_HIGH] << 8) | tdma_rfRxInfo. pPayload[TDMA_DST_LOW]; fd->slot = ((uint16_t) tdma_rfRxInfo.pPayload[TDMA_SLOT_HIGH] << 8) | tdma_rfRxInfo. pPayload[TDMA_SLOT_LOW]; fd->seq_num = ((uint16_t) tdma_rfRxInfo. pPayload[TDMA_SEQ_NUM_HIGH] << 8) | tdma_rfRxInfo. pPayload[TDMA_SEQ_NUM_LOW]; fd->cycle_size = ((uint16_t) tdma_rfRxInfo. pPayload[TDMA_CYCLE_SIZE_HIGH] << 8) | tdma_rfRxInfo. pPayload[TDMA_CYCLE_SIZE_LOW]; // Check if it was a time out instead of packet RX signal if (flags == TDMA_BLOCKING) if ((event & SIG (tdma_rx_pkt_signal)) == 0) return NRK_ERROR; // Set the buffer as empty tdma_rx_buf_empty = 1; return NRK_OK; }
int8_t nrk_signal_create() { uint8_t i=0; for(i=0;i<32;i++) { if( !(_nrk_signal_list & SIG(i))) { _nrk_signal_list|=SIG(i); return i; } } return NRK_ERROR; }
//return the number removed from signal set int8_t nrk_signal_delete(nrk_sig_t sig_id) { uint8_t task_ID; uint32_t sig_mask; sig_mask=SIG(sig_id); if( (sig_mask & _nrk_signal_list)==0) return NRK_ERROR; nrk_int_disable(); for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++){ if(nrk_task_TCB[task_ID].task_ID==-1) continue; // Check for tasks waiting on the signal // If there is a task that is waiting on just this signal // then we need to change it to the normal SUSPEND state if(nrk_task_TCB[task_ID].registered_signal_mask==sig_mask) //check to make sure its only signal its waiting on { // printf("delete t(%i) signal(%li)\r\n",task_ID,nrk_task_TCB[task_ID].registered_signal_mask); nrk_task_TCB[task_ID].active_signal_mask=0; nrk_task_TCB[task_ID].event_suspend=0; nrk_task_TCB[task_ID].task_state=SUSPENDED; } nrk_task_TCB[task_ID].registered_signal_mask&=~sig_mask; //cheaper to remove than do a check nrk_task_TCB[task_ID].active_signal_mask&=~sig_mask; //cheaper to remove than do a check } _nrk_signal_list&=~SIG(sig_id); nrk_int_enable(); return NRK_OK; }
void tx_task () { int8_t v,state,outlet_state,dst_mac, outlet; uint8_t len, cnt; nrk_sig_t uart_rx_signal; char c; printf ("Gateway Tx Task PID=%u\r\n", nrk_get_pid ()); while (!tdma_started ()) nrk_wait_until_next_period (); uart_rx_signal=nrk_uart_rx_signal_get(); nrk_signal_register(uart_rx_signal); cnt = 0; state=0; while (1) { if(nrk_uart_data_ready(NRK_DEFAULT_UART)) { c=getchar(); if(state==1) { dst_mac=c; state=2; } else if(state==2) { outlet=c; state=3; } else if(state==3) { outlet_state=c; state=4; } if(c=='S') state=1; if(c=='E') { if(state==4) { printf( "TX: %d %d %d\r\n",dst_mac, outlet, outlet_state ); tx_buf[0]=dst_mac; tx_buf[1]=outlet; tx_buf[2]=outlet_state; len=3; // Only transmit data if you want to do so // Messages from the host are always broadcasts v = tdma_send (&tx_tdma_fd, &tx_buf, len, TDMA_BLOCKING); if (v == NRK_OK) { nrk_kprintf (PSTR ("Host Packet Sent\n")); } } state=0; } } else nrk_event_wait(SIG(uart_rx_signal)); } }
int8_t isa_wait_until_rx_pkt() { nrk_signal_register(isa_rx_pkt_signal); if (isa_rx_pkt_check() != 0) return NRK_OK; nrk_event_wait (SIG(isa_rx_pkt_signal)); return NRK_OK; }
void task_snd() { uint8_t ret; nrk_sig_t tx_done_signal; uint16_t count=1; // Wait until the rx_task starts up the protocol while (!wd_started ()) nrk_wait_until_next_period (); nrk_wait_until_next_period (); // wait one more period after init tx_done_signal = wd_get_tx_signal (); nrk_signal_register (tx_done_signal); while(1) { nrk_led_toggle(ORANGE_LED); // put just two bytes of payload in the packet... tx_buf[0]=0xCB; tx_buf[1]=MSG_PRIO; // put MSG_PRIO in the payload also // For blocking transmits, just use the following function call. // wd_tx_packet(tx_buf, 2, MSG_PRIO); // This function transmits packets in a non-blocking manner ret = wd_tx_packet_enqueue (tx_buf, 2, MSG_PRIO); // if (ret == NRK_OK) printf ("(%u) Tx packet enqueued\r\n", count); // else printf ("(%u) Tx packet NOT enqueued\r\n", count); if (ret == NRK_OK) nrk_kprintf (PSTR ("t")); else nrk_kprintf (PSTR ("\r\nTx Enqueue error.\r\n")); // This function waits on the tx_done_signal //ret = wd_wait_until_tx_packet(); //if(ret != NRK_OK ) nrk_kprintf (PSTR ("TX error!\r\n")); // Just check result // Or, we do it here... ret = nrk_event_wait (SIG(tx_done_signal) | SIG(nrk_wakeup_signal)); //if(ret & SIG(tx_done_signal)) // printf ("(%u) TX send done \r\n", count++); // Just check result (signal is okay) nrk_wait_until_next_period(); } }
int8_t nrk_event_signal(int8_t sig_id) { uint8_t task_ID; uint8_t event_occured=0; uint32_t sig_mask; sig_mask=SIG(sig_id); // Check if signal was created // Signal was not created if((sig_mask & _nrk_signal_list)==0 ) { _nrk_errno_set(1); return NRK_ERROR;} //needs to be atomic otherwise run the risk of multiple tasks being scheduled late and not in order of priority. nrk_int_disable(); for (task_ID=0; task_ID < NRK_MAX_TASKS; task_ID++){ // if (nrk_task_TCB[task_ID].task_state == EVENT_SUSPENDED) // { // printf( "task %d is event suspended\r\n",task_ID ); if(nrk_task_TCB[task_ID].event_suspend==SIG_EVENT_SUSPENDED) if((nrk_task_TCB[task_ID].active_signal_mask & sig_mask)) { nrk_task_TCB[task_ID].task_state=SUSPENDED; nrk_task_TCB[task_ID].next_wakeup=0; nrk_task_TCB[task_ID].event_suspend=0; // Add the event trigger here so it is returned // from nrk_event_wait() nrk_task_TCB[task_ID].active_signal_mask=sig_mask; event_occured=1; } if(nrk_task_TCB[task_ID].event_suspend==RSRC_EVENT_SUSPENDED) if((nrk_task_TCB[task_ID].active_signal_mask == sig_mask)) { nrk_task_TCB[task_ID].task_state=SUSPENDED; nrk_task_TCB[task_ID].next_wakeup=0; nrk_task_TCB[task_ID].event_suspend=0; // Add the event trigger here so it is returned // from nrk_event_wait() nrk_task_TCB[task_ID].active_signal_mask=0; event_occured=1; } // } } nrk_int_enable(); if(event_occured) { return NRK_OK; } // No task was waiting on the signal _nrk_errno_set(2); return NRK_ERROR; }
// signals void VlcMediaPlayer::d_connect() { #define SIG(signal) connect(d, signal, signal) SIG(SIGNAL(libvlcEvent(const libvlc_event_t *))); SIG(SIGNAL(mediaChanged(libvlc_media_t *))); SIG(SIGNAL(buffering(const float &))); SIG(SIGNAL(stateChanged(const VlcState::Type &))); SIG(SIGNAL(forward())); SIG(SIGNAL(backward())); SIG(SIGNAL(endReached())); SIG(SIGNAL(encounteredError())); SIG(SIGNAL(timeChanged(const qint64 &))); SIG(SIGNAL(positionChanged(const float &))); SIG(SIGNAL(seekableChanged(const int &))); SIG(SIGNAL(pausableChanged(const int &))); SIG(SIGNAL(titleChanged(const int &))); SIG(SIGNAL(snapshotTaken(const QString &))); SIG(SIGNAL(lengthChanged(const qint64 &))); SIG(SIGNAL(voutChanged(const int &))); #undef SIG }
static nserror mimesniff__match_unknown_bom(const uint8_t *data, size_t len, lwc_string **effective_type) { #define SIG(t, s, x) { (const uint8_t *) s, SLEN(s), x, t } static const struct map_s bom_match_types[] = { SIG(&text_plain, "\xfe\xff", false), SIG(&text_plain, "\xff\xfe", false), SIG(&text_plain, "\xef\xbb\xbf", false), { NULL, 0, false, NULL } }; #undef SIG const struct map_s *it; for (it = bom_match_types; it->sig != NULL; it++) { if (it->len <= len && memcmp(data, it->sig, it->len) == 0) { *effective_type = lwc_string_ref(*it->type); return NSERROR_OK; } } return NSERROR_NOT_FOUND; }
int8_t nrk_signal_unregister(int8_t sig_id) { uint32_t sig_mask; sig_mask=SIG(sig_id); if(nrk_cur_task_TCB->registered_signal_mask & sig_mask) { nrk_cur_task_TCB->registered_signal_mask&=~(sig_mask); nrk_cur_task_TCB->active_signal_mask&=~(sig_mask); } else return NRK_ERROR; return NRK_OK; }
static nserror mimesniff__match_unknown_riff(const uint8_t *data, size_t len, lwc_string **effective_type) { #define SIG(t, s, x) { (const uint8_t *) s, SLEN(s), x, t } static const struct map_s riff_match_types[] = { SIG(&image_webp, "WEBPVP", true), SIG(&audio_wave, "WAVE", true), { NULL, 0, false, NULL } }; #undef SIG const struct map_s *it; for (it = riff_match_types; it->sig != NULL; it++) { if (it->len + SLEN("RIFF????") <= len && memcmp(data, "RIFF", SLEN("RIFF")) == 0 && memcmp(data + SLEN("RIFF????"), it->sig, it->len) == 0) { *effective_type = lwc_string_ref(*it->type); return NSERROR_OK; } } return NSERROR_NOT_FOUND; }
int main(int argc, char const *argv[], char const *envp[]) { PRE(); DCL(); EXP(); INT(); FLP(); ARR(); STR(); MEM(); ENV(envp); SIG(); ERR(); MSC(); POS(); return 0; }
static nserror mimesniff__compute_image(lwc_string *official_type, const uint8_t *data, size_t len, lwc_string **effective_type) { #define SIG(t, s) { (const uint8_t *) s, SLEN(s), t } static const struct it_s { const uint8_t *sig; size_t len; lwc_string **type; } image_types[] = { SIG(&image_gif, "GIF87a"), SIG(&image_gif, "GIF89a"), SIG(&image_png, "\x89PNG\r\n\x1a\n"), SIG(&image_jpeg, "\xff\xd8\xff"), SIG(&image_bmp, "BM"), SIG(&image_vnd_microsoft_icon, "\x00\x00\x01\x00"), { NULL, 0, NULL } }; #undef SIG const struct it_s *it; if (data == NULL) { lwc_string_unref(official_type); return NSERROR_NEED_DATA; } for (it = image_types; it->sig != NULL; it++) { if (it->len <= len && memcmp(data, it->sig, it->len) == 0) { lwc_string_unref(official_type); *effective_type = lwc_string_ref(*it->type); return NSERROR_OK; } } /* WebP has a signature that doesn't fit into the above table */ if (SLEN("RIFF????WEBPVP") <= len && memcmp(data, "RIFF", SLEN("RIFF")) == 0 && memcmp(data + SLEN("RIFF????"), "WEBPVP", SLEN("WEBPVP")) == 0 ) { lwc_string_unref(official_type); *effective_type = lwc_string_ref(image_webp); return NSERROR_OK; } *effective_type = official_type; return NSERROR_OK; }
uint32_t nrk_event_wait(uint32_t event_mask) { // FIXME: Should go through list and check that all masks are registered, not just 1 if(event_mask & nrk_cur_task_TCB->registered_signal_mask) { nrk_cur_task_TCB->active_signal_mask=event_mask; nrk_cur_task_TCB->event_suspend=SIG_EVENT_SUSPENDED; } else { return 0; } if(event_mask & SIG(nrk_wakeup_signal)) nrk_wait_until_nw(); else nrk_wait_until_ticks(0); //unmask the signal when its return so it has logical value like 1 to or whatever was user defined return ( (nrk_cur_task_TCB->active_signal_mask)); }
void sig_handler(int sig) { char stack_text[10000]; print_backtrace(stack_text, sizeof(stack_text), 30); char const* sig_name = 0; switch (sig) { #define SIG(x) case x: sig_name = #x; break SIG(SIGSEGV); #ifdef SIGBUS SIG(SIGBUS); #endif SIG(SIGILL); SIG(SIGABRT); SIG(SIGFPE); #ifdef SIGSYS SIG(SIGSYS); #endif #undef SIG }; fprintf(stderr, "signal: %s caught:\n%s\n", sig_name, stack_text); exit(138); }
static void periodic_task() { nrk_sig_mask_t wait_mask, func_wait_mask; nrk_time_t next_event, func_next_event; periodic_func_t **funcp; periodic_func_t *func; nrk_time_t now, sleep_time; int8_t rc; funcp = &functions[0]; while (*funcp) { func = *funcp; LOG("init: "); LOGF(func->name); LOGNL(); if (func->init) func->init(); funcp++; } rc = nrk_signal_register(func_signal); if (rc == NRK_ERROR) ABORT("reg sig: func\r\n"); while (1) { LOG("awake\r\n"); TIME_CLEAR(next_event); wait_mask = SIG(func_signal); funcp = &functions[0]; while (*funcp) { func = *funcp; TIME_CLEAR(func_next_event); func_wait_mask = 0; if (func->enabled || func->enabled != func->last_enabled) { LOG("proc: "); LOGF(func->name); LOGNL(); ASSERT(func->proc); func->proc(func->enabled, &func_next_event, &func_wait_mask); } func->last_enabled = func->enabled; wait_mask |= func_wait_mask; if (IS_VALID_TIME(func_next_event) && (!IS_VALID_TIME(next_event) || time_cmp(&func_next_event, &next_event) < 0)) { next_event = func_next_event; } funcp++; } if (IS_VALID_TIME(next_event)) { nrk_time_get(&now); rc = nrk_time_sub(&sleep_time, next_event, now); if (rc != NRK_OK) { LOG("next event in the past\r\n"); continue; } LOG("sleeping for: "); LOGP("%lu ms\r\n", TIME_TO_MS(sleep_time)); nrk_set_next_wakeup(sleep_time); wait_mask |= SIG(nrk_wakeup_signal); } LOG("waiting\r\n"); nrk_event_wait( wait_mask ); } ABORT("periodic task exited\r\n"); }
static int parse_rock_ridge_stat_internal(iso9660_dir_t *p_iso9660_dir, iso9660_stat_t *p_stat, int regard_xa) { int len; unsigned char * chr; int symlink_len = 0; CONTINUE_DECLS; if (nope == p_stat->rr.b3_rock) return 0; SETUP_ROCK_RIDGE(p_iso9660_dir, chr, len); if (regard_xa) { chr+=14; len-=14; if (len<0) len=0; } /* repeat:*/ { int sig; iso_extension_record_t * rr; int rootflag; while (len > 1){ /* There may be one byte for padding somewhere */ rr = (iso_extension_record_t *) chr; if (rr->len == 0) goto out; /* Something got screwed up here */ sig = from_721(*chr); chr += rr->len; len -= rr->len; switch(sig){ case SIG('S','P'): CHECK_SP(goto out); break; case SIG('C','E'): CHECK_CE; break; case SIG('E','R'): p_stat->rr.b3_rock = yep; cdio_debug("ISO 9660 Extensions: "); { int p; for(p=0;p<rr->u.ER.len_id;p++) cdio_debug("%c",rr->u.ER.data[p]); } break; case SIG('P','X'): p_stat->rr.st_mode = from_733(rr->u.PX.st_mode); p_stat->rr.st_nlinks = from_733(rr->u.PX.st_nlinks); p_stat->rr.st_uid = from_733(rr->u.PX.st_uid); p_stat->rr.st_gid = from_733(rr->u.PX.st_gid); break; case SIG('P','N'): /* Device major,minor number */ { int32_t high, low; high = from_733(rr->u.PN.dev_high); low = from_733(rr->u.PN.dev_low); /* * The Rock Ridge standard specifies that if sizeof(dev_t) <= 4, * then the high field is unused, and the device number is completely * stored in the low field. Some writers may ignore this subtlety, * and as a result we test to see if the entire device number is * stored in the low field, and use that. */ if((low & ~0xff) && high == 0) { p_stat->rr.i_rdev = CDIO_MKDEV(low >> 8, low & 0xff); } else { p_stat->rr.i_rdev = CDIO_MKDEV(high, low); } } break; case SIG('T','F'): /* Time stamp(s) for a file */ { int cnt = 0; add_time(ISO_ROCK_TF_CREATE, create); add_time(ISO_ROCK_TF_MODIFY, modify); add_time(ISO_ROCK_TF_ACCESS, access); add_time(ISO_ROCK_TF_ATTRIBUTES, attributes); add_time(ISO_ROCK_TF_BACKUP, backup); add_time(ISO_ROCK_TF_EXPIRATION, expiration); add_time(ISO_ROCK_TF_EFFECTIVE, effective); p_stat->rr.b3_rock = yep; break; } case SIG('S','L'): { /* Symbolic link */ uint8_t slen; iso_rock_sl_part_t * p_sl; iso_rock_sl_part_t * p_oldsl; slen = rr->len - 5; p_sl = &rr->u.SL.link; p_stat->rr.i_symlink = symlink_len; while (slen > 1){ rootflag = 0; switch(p_sl->flags &~1){ case 0: realloc_symlink(p_stat, p_sl->len); memcpy(&(p_stat->rr.psz_symlink[p_stat->rr.i_symlink]), p_sl->text, p_sl->len); p_stat->rr.i_symlink += p_sl->len; break; case 4: realloc_symlink(p_stat, 1); p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.'; /* continue into next case. */ case 2: realloc_symlink(p_stat, 1); p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.'; break; case 8: rootflag = 1; realloc_symlink(p_stat, 1); p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/'; p_stat->rr.i_symlink++; break; default: cdio_warn("Symlink component flag not implemented"); } slen -= p_sl->len + 2; p_oldsl = p_sl; p_sl = (iso_rock_sl_part_t *) (((char *) p_sl) + p_sl->len + 2); if (slen < 2) { if (((rr->u.SL.flags & 1) != 0) && ((p_oldsl->flags & 1) == 0)) p_stat->rr.i_symlink += 1; break; } /* * If this component record isn't continued, then append a '/'. */ if (!rootflag && (p_oldsl->flags & 1) == 0) { realloc_symlink(p_stat, 1); p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/'; } } } symlink_len = p_stat->rr.i_symlink; realloc_symlink(p_stat, 1); p_stat->rr.psz_symlink[symlink_len]='\0'; break; case SIG('R','E'): cdio_warn("Attempt to read p_stat for relocated directory"); goto out; #ifdef FINISHED case SIG('C','L'): { iso9660_stat_t * reloc; ISOFS_I(p_stat)->i_first_extent = from_733(rr->u.CL.location); reloc = isofs_iget(p_stat->rr.i_sb, p_stat->rr.i_first_extent, 0); if (!reloc) goto out; p_stat->rr.st_mode = reloc->st_mode; p_stat->rr.st_nlinks = reloc->st_nlinks; p_stat->rr.st_uid = reloc->st_uid; p_stat->rr.st_gid = reloc->st_gid; p_stat->rr.i_rdev = reloc->i_rdev; p_stat->rr.i_symlink = reloc->i_symlink; p_stat->rr.i_blocks = reloc->i_blocks; p_stat->rr.i_atime = reloc->i_atime; p_stat->rr.i_ctime = reloc->i_ctime; p_stat->rr.i_mtime = reloc->i_mtime; iput(reloc); } break; #endif default: break; } }
/*! Get @return length of name field; 0: not found, -1: to be ignored */ int get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir, /*out*/ char * psz_name, /*in/out*/ iso9660_stat_t *p_stat) { int len; unsigned char *chr; int symlink_len = 0; CONTINUE_DECLS; int i_namelen = 0; int truncate=0; if (!p_stat || nope == p_stat->rr.b3_rock) return 0; *psz_name = 0; SETUP_ROCK_RIDGE(p_iso9660_dir, chr, len); /*repeat:*/ { iso_extension_record_t * rr; int sig; int rootflag; while (len > 1){ /* There may be one byte for padding somewhere */ rr = (iso_extension_record_t *) chr; if (rr->len == 0) goto out; /* Something got screwed up here */ sig = *chr+(*(chr+1) << 8); chr += rr->len; len -= rr->len; switch(sig){ case SIG('S','P'): CHECK_SP(goto out); break; case SIG('C','E'): { iso711_t i_fname = from_711(p_iso9660_dir->filename.len); if ('\0' == p_iso9660_dir->filename.str[1] && 1 == i_fname) break; if ('\1' == p_iso9660_dir->filename.str[1] && 1 == i_fname) break; } CHECK_CE; break; case SIG('E','R'): p_stat->rr.b3_rock = yep; cdio_debug("ISO 9660 Extensions: "); { int p; for(p=0;p<rr->u.ER.len_id;p++) cdio_debug("%c",rr->u.ER.data[p]); } break; case SIG('N','M'): /* Alternate name */ p_stat->rr.b3_rock = yep; if (truncate) break; if (rr->u.NM.flags & ISO_ROCK_NM_PARENT) { i_namelen = sizeof(".."); strncat(psz_name, "..", i_namelen); } else if (rr->u.NM.flags & ISO_ROCK_NM_CURRENT) { i_namelen = sizeof("."); strncat(psz_name, ".", i_namelen); break; } if (rr->u.NM.flags & ~1) { cdio_info("Unsupported NM flag settings (%d)",rr->u.NM.flags); break; } if((strlen(psz_name) + rr->len - 5) >= 254) { truncate = 1; break; } strncat(psz_name, rr->u.NM.name, rr->len - 5); i_namelen += rr->len - 5; break; case SIG('P','X'): /* POSIX file attributes */ p_stat->rr.st_mode = from_733(rr->u.PX.st_mode); p_stat->rr.st_nlinks = from_733(rr->u.PX.st_nlinks); p_stat->rr.st_uid = from_733(rr->u.PX.st_uid); p_stat->rr.st_gid = from_733(rr->u.PX.st_gid); p_stat->rr.b3_rock = yep; break; case SIG('S','L'): { /* Symbolic link */ uint8_t slen; iso_rock_sl_part_t * p_sl; iso_rock_sl_part_t * p_oldsl; slen = rr->len - 5; p_sl = &rr->u.SL.link; p_stat->rr.i_symlink = symlink_len; while (slen > 1){ rootflag = 0; switch(p_sl->flags &~1){ case 0: realloc_symlink(p_stat, p_sl->len); memcpy(&(p_stat->rr.psz_symlink[p_stat->rr.i_symlink]), p_sl->text, p_sl->len); p_stat->rr.i_symlink += p_sl->len; break; case 4: realloc_symlink(p_stat, 1); p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.'; /* continue into next case. */ case 2: realloc_symlink(p_stat, 1); p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '.'; break; case 8: rootflag = 1; realloc_symlink(p_stat, 1); p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/'; break; default: cdio_warn("Symlink component flag not implemented"); } slen -= p_sl->len + 2; p_oldsl = p_sl; p_sl = (iso_rock_sl_part_t *) (((char *) p_sl) + p_sl->len + 2); if (slen < 2) { if (((rr->u.SL.flags & 1) != 0) && ((p_oldsl->flags & 1) == 0)) p_stat->rr.i_symlink += 1; break; } /* * If this component record isn't continued, then append a '/'. */ if (!rootflag && (p_oldsl->flags & 1) == 0) { realloc_symlink(p_stat, 1); p_stat->rr.psz_symlink[p_stat->rr.i_symlink++] = '/'; } } } symlink_len = p_stat->rr.i_symlink; realloc_symlink(p_stat, 1); p_stat->rr.psz_symlink[symlink_len]='\0'; break; case SIG('R','E'): free(buffer); return -1; case SIG('T','F'): /* Time stamp(s) for a file */ { int cnt = 0; add_time(ISO_ROCK_TF_CREATE, create); add_time(ISO_ROCK_TF_MODIFY, modify); add_time(ISO_ROCK_TF_ACCESS, access); add_time(ISO_ROCK_TF_ATTRIBUTES, attributes); add_time(ISO_ROCK_TF_BACKUP, backup); add_time(ISO_ROCK_TF_EXPIRATION, expiration); add_time(ISO_ROCK_TF_EFFECTIVE, effective); p_stat->rr.b3_rock = yep; break; } default: break; } } } free(buffer); return i_namelen; /* If 0, this file did not have a NM field */ out: free(buffer); return 0; }
static int parse_rock_ridge_inode_internal(struct iso_directory_record *de, struct inode *inode, int regard_xa) { int symlink_len = 0; int cnt, sig; struct inode *reloc; struct rock_ridge *rr; int rootflag; struct rock_state rs; int ret = 0; if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; init_rock_state(&rs, inode); setup_rock_ridge(de, inode, &rs); if (regard_xa) { rs.chr += 14; rs.len -= 14; if (rs.len < 0) rs.len = 0; } repeat: while (rs.len > 2) { /* There may be one byte for padding somewhere */ rr = (struct rock_ridge *)rs.chr; /* * Ignore rock ridge info if rr->len is out of range, but * don't return -EIO because that would make the file * invisible. */ if (rr->len < 3) goto out; /* Something got screwed up here */ sig = isonum_721(rs.chr); if (rock_check_overflow(&rs, sig)) goto eio; rs.chr += rr->len; rs.len -= rr->len; /* * As above, just ignore the rock ridge info if rr->len * is bogus. */ if (rs.len < 0) goto out; /* Something got screwed up here */ switch (sig) { #ifndef CONFIG_ZISOFS /* No flag for SF or ZF */ case SIG('R', 'R'): if ((rr->u.RR.flags[0] & (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) goto out; break; #endif case SIG('S', 'P'): if (check_sp(rr, inode)) goto out; break; case SIG('C', 'E'): rs.cont_extent = isonum_733(rr->u.CE.extent); rs.cont_offset = isonum_733(rr->u.CE.offset); rs.cont_size = isonum_733(rr->u.CE.size); break; case SIG('E', 'R'): ISOFS_SB(inode->i_sb)->s_rock = 1; printk(KERN_DEBUG "ISO 9660 Extensions: "); { int p; for (p = 0; p < rr->u.ER.len_id; p++) printk("%c", rr->u.ER.data[p]); } printk("\n"); break; case SIG('P', 'X'): inode->i_mode = isonum_733(rr->u.PX.mode); set_nlink(inode, isonum_733(rr->u.PX.n_links)); inode->i_uid = isonum_733(rr->u.PX.uid); inode->i_gid = isonum_733(rr->u.PX.gid); break; case SIG('P', 'N'): { int high, low; high = isonum_733(rr->u.PN.dev_high); low = isonum_733(rr->u.PN.dev_low); /* * The Rock Ridge standard specifies that if * sizeof(dev_t) <= 4, then the high field is * unused, and the device number is completely * stored in the low field. Some writers may * ignore this subtlety, * and as a result we test to see if the entire * device number is * stored in the low field, and use that. */ if ((low & ~0xff) && high == 0) { inode->i_rdev = MKDEV(low >> 8, low & 0xff); } else { inode->i_rdev = MKDEV(high, low); } } break; case SIG('T', 'F'): /* * Some RRIP writers incorrectly place ctime in the * TF_CREATE field. Try to handle this correctly for * either case. */ /* Rock ridge never appears on a High Sierra disk */ cnt = 0; if (rr->u.TF.flags & TF_CREATE) { inode->i_ctime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); inode->i_ctime.tv_nsec = 0; } if (rr->u.TF.flags & TF_MODIFY) { inode->i_mtime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); inode->i_mtime.tv_nsec = 0; } if (rr->u.TF.flags & TF_ACCESS) { inode->i_atime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); inode->i_atime.tv_nsec = 0; } if (rr->u.TF.flags & TF_ATTRIBUTES) { inode->i_ctime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0); inode->i_ctime.tv_nsec = 0; } break; case SIG('S', 'L'): { int slen; struct SL_component *slp; struct SL_component *oldslp; slen = rr->len - 5; slp = &rr->u.SL.link; inode->i_size = symlink_len; while (slen > 1) { rootflag = 0; switch (slp->flags & ~1) { case 0: inode->i_size += slp->len; break; case 2: inode->i_size += 1; break; case 4: inode->i_size += 2; break; case 8: rootflag = 1; inode->i_size += 1; break; default: printk("Symlink component flag " "not implemented\n"); } slen -= slp->len + 2; oldslp = slp; slp = (struct SL_component *) (((char *)slp) + slp->len + 2); if (slen < 2) { if (((rr->u.SL. flags & 1) != 0) && ((oldslp-> flags & 1) == 0)) inode->i_size += 1; break; } /* * If this component record isn't * continued, then append a '/'. */ if (!rootflag && (oldslp->flags & 1) == 0) inode->i_size += 1; } } symlink_len = inode->i_size; break; case SIG('R', 'E'): printk(KERN_WARNING "Attempt to read inode for " "relocated directory\n"); goto out; case SIG('C', 'L'): ISOFS_I(inode)->i_first_extent = isonum_733(rr->u.CL.location); reloc = isofs_iget(inode->i_sb, ISOFS_I(inode)->i_first_extent, 0); if (IS_ERR(reloc)) { ret = PTR_ERR(reloc); goto out; } inode->i_mode = reloc->i_mode; set_nlink(inode, reloc->i_nlink); inode->i_uid = reloc->i_uid; inode->i_gid = reloc->i_gid; inode->i_rdev = reloc->i_rdev; inode->i_size = reloc->i_size; inode->i_blocks = reloc->i_blocks; inode->i_atime = reloc->i_atime; inode->i_ctime = reloc->i_ctime; inode->i_mtime = reloc->i_mtime; iput(reloc); break; #ifdef CONFIG_ZISOFS case SIG('Z', 'F'): { int algo; if (ISOFS_SB(inode->i_sb)->s_nocompress) break; algo = isonum_721(rr->u.ZF.algorithm); if (algo == SIG('p', 'z')) { int block_shift = isonum_711(&rr->u.ZF.parms[1]); if (block_shift > 17) { printk(KERN_WARNING "isofs: " "Can't handle ZF block " "size of 2^%d\n", block_shift); } else { /* * Note: we don't change * i_blocks here */ ISOFS_I(inode)->i_file_format = isofs_file_compressed; /* * Parameters to compression * algorithm (header size, * block size) */ ISOFS_I(inode)->i_format_parm[0] = isonum_711(&rr->u.ZF.parms[0]); ISOFS_I(inode)->i_format_parm[1] = isonum_711(&rr->u.ZF.parms[1]); inode->i_size = isonum_733(rr->u.ZF. real_size); } } else { printk(KERN_WARNING "isofs: Unknown ZF compression " "algorithm: %c%c\n", rr->u.ZF.algorithm[0], rr->u.ZF.algorithm[1]); } break; } #endif default: break; }
/* * return length of name field; 0: not found, -1: to be ignored */ int get_rock_ridge_filename(struct iso_directory_record *de, char *retname, struct inode *inode) { struct rock_state rs; struct rock_ridge *rr; int sig; int retnamlen = 0; int truncate = 0; int ret = 0; if (!ISOFS_SB(inode->i_sb)->s_rock) return 0; *retname = 0; init_rock_state(&rs, inode); setup_rock_ridge(de, inode, &rs); repeat: while (rs.len > 2) { /* There may be one byte for padding somewhere */ rr = (struct rock_ridge *)rs.chr; /* * Ignore rock ridge info if rr->len is out of range, but * don't return -EIO because that would make the file * invisible. */ if (rr->len < 3) goto out; /* Something got screwed up here */ sig = isonum_721(rs.chr); if (rock_check_overflow(&rs, sig)) goto eio; rs.chr += rr->len; rs.len -= rr->len; /* * As above, just ignore the rock ridge info if rr->len * is bogus. */ if (rs.len < 0) goto out; /* Something got screwed up here */ switch (sig) { case SIG('R', 'R'): if ((rr->u.RR.flags[0] & RR_NM) == 0) goto out; break; case SIG('S', 'P'): if (check_sp(rr, inode)) goto out; break; case SIG('C', 'E'): rs.cont_extent = isonum_733(rr->u.CE.extent); rs.cont_offset = isonum_733(rr->u.CE.offset); rs.cont_size = isonum_733(rr->u.CE.size); break; case SIG('N', 'M'): if (truncate) break; if (rr->len < 5) break; /* * If the flags are 2 or 4, this indicates '.' or '..'. * We don't want to do anything with this, because it * screws up the code that calls us. We don't really * care anyways, since we can just use the non-RR * name. */ if (rr->u.NM.flags & 6) break; if (rr->u.NM.flags & ~1) { printk("Unsupported NM flag settings (%d)\n", rr->u.NM.flags); break; } if ((strlen(retname) + rr->len - 5) >= 254) { truncate = 1; break; } strncat(retname, rr->u.NM.name, rr->len - 5); retnamlen += rr->len - 5; break; case SIG('R', 'E'): kfree(rs.buffer); return -1; default: break; } } ret = rock_continue(&rs); if (ret == 0) goto repeat; if (ret == 1) return retnamlen; /* If 0, this file did not have a NM field */ out: kfree(rs.buffer); return ret; eio: ret = -EIO; goto out; }
/* * We think there's a record of type `sig' at rs->chr. Parse the signature * and make sure that there's really room for a record of that type. */ static int rock_check_overflow(struct rock_state *rs, int sig) { int len; switch (sig) { case SIG('S', 'P'): len = sizeof(struct SU_SP_s); break; case SIG('C', 'E'): len = sizeof(struct SU_CE_s); break; case SIG('E', 'R'): len = sizeof(struct SU_ER_s); break; case SIG('R', 'R'): len = sizeof(struct RR_RR_s); break; case SIG('P', 'X'): len = sizeof(struct RR_PX_s); break; case SIG('P', 'N'): len = sizeof(struct RR_PN_s); break; case SIG('S', 'L'): len = sizeof(struct RR_SL_s); break; case SIG('N', 'M'): len = sizeof(struct RR_NM_s); break; case SIG('C', 'L'): len = sizeof(struct RR_CL_s); break; case SIG('P', 'L'): len = sizeof(struct RR_PL_s); break; case SIG('T', 'F'): len = sizeof(struct RR_TF_s); break; case SIG('Z', 'F'): len = sizeof(struct RR_ZF_s); break; default: len = 0; break; } len += offsetof(struct rock_ridge, u); if (len > rs->len) { printk(KERN_NOTICE "rock: directory entry would overflow " "storage\n"); printk(KERN_NOTICE "rock: sig=0x%02x, size=%d, remaining=%d\n", sig, len, rs->len); return -EIO; } return 0; }