unsigned char Ax_Send( volatile unsigned char *message_global, int str_length) { int i; debug_puts("\n message length... \t"); debug_putdec(str_length); debug_puts("\n/////////\n"); for(i=0;i<str_length;i++){ FM_buffer[FM_buffer_num][i]=message_global[i]; debug_puthex(message_global[i]); debug_puts(","); } debug_puts("\n---------\n"); for(i=0;i<str_length;i++){ debug_putc(message_global[i]); } debug_puts("\n/////////\n"); FM_buffer_length[FM_buffer_num]=str_length; FM_buffer_num++; if(FM_buffer_num>FM_BUFFER_MAX-1){ FM_buffer_num=0; } if(FM_mode==0||FM_mode==3){ FM_mode=1; //モード0ならtonさせる } return 1; }
uint16_t mem_write(uint16_t id, uint16_t offset, const void *buf, uint16_t count) { #if 0 debug_puts("Writing to "); debug_puthex(id+offset); debug_nl(); print_buf(buf, count); debug_nl(); #endif spi_mem_write(id+offset, buf, count); return count; }
uint16_t mem_read(uint16_t id, uint16_t offset, void *buf, uint16_t count) { spi_mem_read(id+offset, buf, count); #if 0 debug_puts("Read from "); debug_puthex(id+offset); debug_nl(); print_buf(buf, count); debug_nl(); #endif return count; }
uint8_t file_submit_call(uint8_t channel_no, uint8_t type, uint8_t *cmd_buffer, errormsg_t *errormsg, rtconfig_t *rtconf, void (*callback)(int8_t errnum, uint8_t *rxdata), uint8_t iscmd) { assert_not_null(errormsg, "file_submit_call: errormsg is null"); assert_not_null(rtconf, "file_submit_call: rtconf is null"); // check for default drive (here is the place to set the last used one) if (nameinfo.drive == NAMEINFO_LAST_DRIVE) { nameinfo.drive = rtconf->last_used_drive; } else if (nameinfo.drive == NAMEINFO_UNUSED_DRIVE) { // TODO: match CBM behavior nameinfo.drive = rtconf->last_used_drive; } else if (nameinfo.drive < MAX_DRIVES) { // only save real drive numbers as last used default rtconf->last_used_drive = nameinfo.drive; } // if second name does not have a drive, use drive from first, // but only if it is defined if (nameinfo.file[0].drive == NAMEINFO_UNUSED_DRIVE && nameinfo.drive != NAMEINFO_UNDEF_DRIVE) { nameinfo.file[0].drive = nameinfo.drive; } // here is the place to plug in other file system providers, // like SD-Card, or even an outgoing IEC or IEEE, to convert between // the two bus systems. This is done depending on the drive number // and managed with the ASSIGN call. //provider_t *provider = &serial_provider; endpoint_t *endpoint = NULL; if (type == FS_OPEN_DIRECT) { debug_printf("Getting direct endpoint provider for channel %d\n", channel_no); endpoint = direct_provider(); } else { endpoint = provider_lookup(nameinfo.drive, (char*) nameinfo.drivename); } // convert from bus' PETSCII to provider // currently only up to the first zero byte is converted, options like file type // are still ASCII only // in the future the bus may have an own conversion option... cconv_converter(CHARSET_PETSCII, endpoint->provider->charset(endpoint->provdata)) ((char*)nameinfo.name, strlen((char*)nameinfo.name), (char*)nameinfo.name, strlen((char*)nameinfo.name)); for (uint8_t i=0 ; i < nameinfo.num_files ; ++i) { if (nameinfo.file[i].name != NULL) { cconv_converter(CHARSET_PETSCII, endpoint->provider->charset(endpoint->provdata)) ((char*)nameinfo.file[i].name, strlen((char*)nameinfo.file[i].name), (char*)nameinfo.file[i].name, strlen((char*)nameinfo.file[i].name)); } } if (type == FS_MOVE && nameinfo.file[0].drive != NAMEINFO_UNUSED_DRIVE // then use ep from first drive anyway && nameinfo.file[0].drive != nameinfo.drive) { // no need to check if the same // two-name command(s) with possibly different drive numbers endpoint_t *endpoint2 = provider_lookup(nameinfo.file[0].drive, (char*) nameinfo.file[0].name); if (endpoint2 != endpoint) { debug_printf("ILLEGAL DRIVE COMBINATION: %d vs. %d\n", nameinfo.drive+0x30, nameinfo.file[0].drive+0x30); set_error_tsd(errormsg, CBM_ERROR_DRIVE_NOT_READY, 0, 0, nameinfo.drive); return -1; } } // check the validity of the drive (note that in general provider_lookup // returns a default provider - serial-over-USB to the PC, which then // may do further checks if (endpoint == NULL) { debug_puts("ILLEGAL DRIVE: "); debug_putc(0x30+nameinfo.drive); debug_putcrlf(); set_error_tsd(errormsg, CBM_ERROR_DRIVE_NOT_READY, 0, 0, nameinfo.drive); return -1; } provider_t *provider = endpoint->provider; // find open slot //int8_t slot = -1; open_t *activeslot = NULL; for (uint8_t i = 0; i < MAX_ACTIVE_OPEN; i++) { if (active[i].channel_no < 0) { //slot = i; activeslot = (open_t*) &active[i]; break; } } //if (slot < 0) { if (activeslot == NULL) { debug_puts("NO OPEN SLOT FOR OPEN!"); debug_putcrlf(); set_error_tsd(errormsg, CBM_ERROR_NO_CHANNEL, 0, 0, nameinfo.drive); return -1; } activeslot->endpoint = endpoint; uint8_t len = assemble_filename_packet(cmd_buffer, &nameinfo); #ifdef DEBUG_FILE debug_printf("LEN AFTER ASSEMBLE=%d\n", len); #endif packet_init(&activeslot->txbuf, len, cmd_buffer); // store pointer to runtime config in packet // used by providers running on the device activeslot->txbuf.rtc = rtconf; packet_set_filled(&activeslot->txbuf, channel_no, type, len); if (!iscmd) { // only for file opens // note: we need the provider for the dir converter, // so we can only do it in here. // open channel uint8_t writetype = WTYPE_READONLY; if (type == FS_OPEN_WR || type == FS_OPEN_AP || type == FS_OPEN_OW) { writetype = WTYPE_WRITEONLY; } else if (type == FS_OPEN_RW) { writetype = WTYPE_READWRITE; } if (nameinfo.options & NAMEOPT_NONBLOCKING) { writetype |= WTYPE_NONBLOCKING; } int8_t (*converter)(void *, packet_t*, uint8_t) = (type == FS_OPEN_DR) ? (provider->directory_converter) : NULL; // TODO: if provider->channel_* are not NULL, we should probably not allocate a channel // but that would break the FILE OPEN detection here. channel_t *channel = channel_find(channel_no); if (channel != NULL) { // clean up channel_close(channel_no); // Note: it seems possible to open the same channel multiple times // on a direct file if (type != FS_OPEN_DIRECT) { debug_puts("FILE OPEN ERROR"); debug_putcrlf(); set_error_tsd(errormsg, CBM_ERROR_NO_CHANNEL, 0, 0, nameinfo.drive); return -1; } } int8_t e = channel_open(channel_no, writetype, endpoint, converter, nameinfo.drive); if (e < 0) { debug_puts("E="); debug_puthex(e); debug_putcrlf(); set_error_tsd(errormsg, CBM_ERROR_NO_CHANNEL, 0, 0, nameinfo.drive); return -1; } } activeslot->callback = callback; // no more error here, just the submit. // so callers can be sure if this function returns <0, they do not need // to close the channel, as it has not been opened // If this function returns 0, a callback must be received and handled, // and the channel is already opened. activeslot->channel_no = channel_no; // prepare response buffer packet_init(&activeslot->rxbuf, OPEN_RX_DATA_LEN, activeslot->rxdata); provider->submit_call(endpoint->provdata, channel_no, &activeslot->txbuf, &activeslot->rxbuf, _file_open_callback); return 0; }
void handle_icmp(uint8_t *macSource, uint8_t *sourceAddr, uint8_t *destIPAddr, uint16_t length, DATA_CB dataCb, void *priv) { /** +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + Message Body + | | */ /* Allocate just enough data to handle the type, code, and checksum fields */ uint8_t buf[4]; uint8_t type; CHECK_SP("handle_icmp: "); #ifdef DEBUG_ICMP PRINT_SP("handle_icmp: "); #endif dataCb(buf, 4, priv); type = buf[0]; #ifdef DEBUG_ICMP debug_puts("Payload size: "); debug_puthex(length); debug_nl(); debug_puts("ICMP Type:"); debug_puthex(type); debug_nl(); #endif /*calc_checksum(payload, 4); uint16_t r = dataCb(payload, length - 4, priv); calc_checksum(payload, length - 4); if (checksum != 0xFFFF) { debug_puts("Checksum error"); debug_nl(); return; }*/ if (net_state != STATE_IDLE && type != ICMP_TYPE_NEIGHBOR_SOLICITATION && type != ICMP_TYPE_NEIGHBOR_ADVERTISMENT) { debug_puts("Not in a state to receive ICMP message"); debug_nl(); return; } switch (type) { case ICMP_TYPE_NEIGHBOR_SOLICITATION: /* First 4 bytes are 'reserved', we ignore them. but must read them */ dataCb(buf, 4, priv); /* Next 16 bytes are the target address. We assume it's one of our addresses as it was passed to us by handle_ipv6() */ /* We only reply if there is a source link-layer address option */ if (length > 20) { uint8_t addr[16]; /* Read address*/ dataCb(addr, 16, priv); /* Read option 'header' */ dataCb(buf, 2, priv); if (buf[0] == 0x01) { uint8_t mac_addr[6]; dataCb(mac_addr, 6, priv); /* We now got the link-layer address and IPv6 address of someone, store it */ register_mac_addr(mac_addr, sourceAddr); send_neighbor_advertisment(mac_addr, addr, sourceAddr, addr); } } break; case ICMP_TYPE_NEIGHBOR_ADVERTISMENT: { /* We ignore first 4 bytes */ uint8_t received_addr[16]; dataCb(buf, 4, priv); dataCb(received_addr, 16, priv); if (net_state == STATE_DAD) { uint8_t addr[16]; net_get_address(ADDRESS_STORE_LINK_LOCAL_OFFSET, addr); if (memcmp(received_addr, addr, 16) == 0) { net_state = STATE_INVALID; return; } } register_mac_addr(macSource, received_addr); net_state = STATE_IDLE; } break; case ICMP_TYPE_ECHO_REQUEST: if (length >= 8) { dataCb(buf, 4, priv); uint16_t id = (buf[0] << 8) | buf[1]; uint16_t seqNo = (buf[2] << 8) | buf[3]; struct ipv6_packet_arg arg; arg.dst_mac_addr = null_mac; arg.dst_ipv6_addr = sourceAddr; arg.src_ipv6_addr = destIPAddr; //arg.payload_length = SIZE_ICMP_HEADER + length; arg.protocol = PROTO_ICMP; net_start_ipv6_packet(&arg); net_send_icmp_start(ICMP_TYPE_ECHO_REPLY, 0); net_send_data(buf, 4); calc_checksum(buf, 4); uint16_t count; length -= 8; while( (count=dataCb(buf, 4, priv)) > 0 && length > 0) { net_send_data(buf, count); calc_checksum(buf, count); } //net_send_icmp(ICMP_TYPE_ECHO_REPLY, 0, payload, length); net_end_ipv6_packet(); } break; case ICMP_TYPE_ROUTER_ADVERTISMENT: /* Ignore first 12 bytes, as we are only interested in addresses. Next, loop through the options in the payload */ { if( length > 140 ) { debug_puts("Lengths exceeds 140 Bytes, ignore router advertisment in order to avoid trouble"); debug_nl(); return; } uint8_t payload[length-4]; CHECK_SP("handle_icmp, ICMP_TYPE_ROUTER_ADVERTISMENT: "); dataCb(payload, length-4, priv); uint8_t *c = payload + 12; while (c < payload + length - 4) { if (c[0] == 3) { uint8_t prefixLength = c[2]; /* Prefix starts at offset 16 */ uint8_t buf[16]; net_get_address(ADDRESS_STORE_MAIN_OFFSET, buf); if (buf[0] == 0x00) { // null_mac as destination means link-local (go figure) routing_table_add(c + 16, prefixLength / 8, null_mac); // Default route routing_table_add(unspec_addr, 0, macSource); assign_address_from_prefix(c + 16, prefixLength); //mem_write(default_route_mac_id, 0, macSource, 6); } else { } } c += c[1] * 8; } } break; } }
/************************************************* ミッションCPU起動(タイマ予約型) *************************************************/ unsigned char ScheduledRequestMissionReboot(volatile unsigned char* param, unsigned char param_length){ int i; smr_time=0; for(i=0;i<param_length;i++){ smr_time=smr_time*10+(unsigned long int)(param[i]-48); } /* smr_timeが大きすぎないかを確かめる */ /* if((smr_time>=4294967296)||(param_length>=10)){ smr_time=0; Ax_Send("r-g-c-smr-INVALID message:smr_time > the LIMIT. \r\n",50); debug_puts("\n INVALID message header with SCI1: smr_time beyonds the limit (4294967296) "); debug_puts("\n request is: "); debug_putdec(smr_time); debug_puts("\n"); return 1; } */ /* smr_timeが現在の時間を超えていないかを確かめる */ /* else if(smr_time<mission_cnt){ smr_time=0; Ax_Send("r-g-c-smr-INVALID message:smr_time > mission_cnt. \r\n",52); debug_puts("\n INVALID message header with SCI1: smr_time > mission_cnt "); debug_puts("\n request is: "); debug_putdec(smr_time); debug_puts("\n obc_time is: "); debug_putdec(mission_cnt); debug_puts("\n"); return 1; } */ debug_puts("\n param_length: "); debug_putdec(param_length); debug_puts("\n request is: "); debug_putdec(smr_time); debug_puts("\n obc_time is: "); debug_putdec(mission_cnt); debug_puts("\n"); unsigned char message_smr[21]; message_smr[0]='r'; message_smr[1]='-'; message_smr[2]='g'; message_smr[3]='-'; message_smr[4]='c'; message_smr[5]='-'; message_smr[6]='s'; message_smr[7]='m'; message_smr[8]='r'; message_smr[9]='-'; message_smr[10]=(smr_time>>24); message_smr[11]=(smr_time>>16); message_smr[12]=(smr_time>>8); message_smr[13]=smr_time; message_smr[14]=(mission_cnt>>24); message_smr[15]=(mission_cnt>>16); message_smr[16]=(mission_cnt>>8); message_smr[17]=mission_cnt; message_smr[18]=0x20; message_smr[19]=0x0d; message_smr[20]=0x0a; Ax_Send(message_smr,21); debug_puts("\n r-g-c-smr-"); debug_puthex(message_smr[10]); debug_puts(" "); debug_puthex(message_smr[11]); debug_puts(" "); debug_puthex(message_smr[12]); debug_puts(" "); debug_puthex(message_smr[13]); debug_puts(" "); debug_puthex(message_smr[14]); debug_puts(" "); debug_puthex(message_smr[15]); debug_puts(" "); debug_puthex(message_smr[16]); debug_puts(" "); debug_puthex(message_smr[17]); return 1; }
/************************************************* ミッションCPU起動(タイマ予約&作動時間指定型) *************************************************/ unsigned char ScheduledRequestMissionSwitch(volatile unsigned char* param, unsigned char param_length){ int i,sms_length=0; sms_time=0; smr_time=0; /* . の前は起動している時間を表す */ for(i=0;i<param_length;i++){ if(param[i]==0x2e){ sms_length=i; break; } sms_time=sms_time*10+(unsigned long int)(param[i]-48); } /* . が一回も出てこない場合はエラー */ if(sms_length==0){ Ax_Send("r-g-c-sms-Error1 \r\n",19); // debug_puts("\n INVALID message header with SCI1: SMS needs . between two variables \n"); return 1; } /* . の後は起動する時間を表す */ for(i=sms_length+1;i<param_length;i++){ smr_time=smr_time*10+(unsigned long int)(param[i]-48); } /* sms_timeを終了する時間にする */ sms_time=sms_time+smr_time; /* smr_timeが大きすぎないかを確かめる */ /* if(smr_time>=4294967296||(param_length-sms_length>10)){ int ex_smr=smr_time; sms_time=0; smr_time=0; Ax_Send("r-g-c-smr-INVALID message:smr_time > the LIMIT. \r\n",50); debug_puts("\n INVALID message header with SCI1: smr_time beyonds the limit (4294967296) "); debug_puts("\n request is: "); debug_putdec(ex_smr); debug_puts("\n"); return 1; } */ /* sms_timeが大きすぎないかを確かめる if(sms_time>=(4294967296-smr_time)||(sms_length>10)){ int ex_sms=sms_time; sms_time=0; smr_time=0; Ax_Send("r-g-c-smr-INVALID message:sms_time > the LIMIT. \r\n",50); debug_puts("\n INVALID message header with SCI1: sms_time beyonds the limit (4294967296) "); debug_puts("\n request is: "); debug_putdec(ex_sms); debug_puts("\n"); return 1; } */ /* smr_timeが現在の時間を超えているかを確かめる */ /* else if(smr_time<mission_cnt){ int ex_smr=smr_time; sms_time=0; smr_time=0; Ax_Send("r-g-c-smr-INVALID message:smr_time > mission_cnt. \r\n",52); debug_puts("\n INVALID message header with SCI1: smr_time beyonds mission_cnt "); debug_puts("\n request is: "); debug_putdec(ex_smr); debug_puts("\n obc_time is: "); debug_putdec(mission_cnt); debug_puts("\n"); return 1; } */ /* debug_puts("\n param_length: "); debug_putdec(param_length-1); debug_puts("\n sms_length: "); debug_putdec(sms_length); debug_puts("\n smr_length: "); debug_putdec(param_length-sms_length-1); debug_puts("\n itu1_cnt time: "); debug_putdec(mission_cnt); debug_puts("\n sms_time time: "); debug_putdec(sms_time); debug_puts("\n smr_time time: "); debug_putdec(smr_time); debug_puts("\n"); */ i=0; unsigned char message_sms[32]; message_sms[i++]='r'; message_sms[i++]='-'; message_sms[i++]='g'; message_sms[i++]='-'; message_sms[i++]='c'; message_sms[i++]='-'; message_sms[i++]='s'; message_sms[i++]='m'; message_sms[i++]='s'; message_sms[i++]='-'; message_sms[i++]=(smr_time>>24); message_sms[i++]=(smr_time>>16); message_sms[i++]=(smr_time>>8); message_sms[i++]=smr_time; message_sms[i++]=(sms_time>>24); message_sms[i++]=(sms_time>>16); message_sms[i++]=(sms_time>>8); message_sms[i++]=sms_time; message_sms[i++]=(mission_cnt>>24); message_sms[i++]=(mission_cnt>>16); message_sms[i++]=(mission_cnt>>8); message_sms[i++]=mission_cnt; message_sms[i++]=0x20; message_sms[i++]=0x0d; message_sms[i++]=0x0a; Ax_Send(message_sms,i);//たぶん長さは25 debug_puts("\n smr_time time:\t"); debug_puthex(message_sms[10]); debug_puthex(message_sms[11]); debug_puthex(message_sms[12]); debug_puthex(message_sms[13]); debug_puts("\n sms_time time:\t"); debug_puthex(message_sms[14]); debug_puthex(message_sms[15]); debug_puthex(message_sms[16]); debug_puthex(message_sms[17]); debug_puts("\n obc time:\t"); debug_puthex(message_sms[18]); debug_puthex(message_sms[19]); debug_puthex(message_sms[20]); debug_puthex(message_sms[21]); return 1; }