Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
File: file.c Progetto: fachat/XD2031
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;
}
Esempio n. 5
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;
	}
}
Esempio n. 6
0
/*************************************************
        ミッション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;
}
Esempio n. 7
0
/*************************************************
        ミッション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;
}