Ejemplo n.º 1
0
/**
 * SIM800 IP configuration commands fail if the IP application is running,
 * even though the configuration settings are already right. The following
 * monkey dance is therefore needed.
 */
static int sim800_config(struct cellular *modem, const char *option, const char *value, int attempts)
{
    at_set_timeout(modem->at, 10);

    for (int i=0; i<attempts; i++) {
        /* Blindly try to set the configuration option. */
        at_command(modem->at, "AT+%s=%s", option, value);

        /* Query the setting status. */
        const char *response = at_command(modem->at, "AT+%s?", option);
        /* Bail out on timeouts. */
        if (response == NULL)
            return -1;

        /* Check if the setting has the correct value. */
        char expected[16];
        if (snprintf(expected, sizeof(expected), "+%s: %s", option, value) >= (int) sizeof(expected)) {
            return -1;
        }
        if (!strcmp(response, expected))
            return 0;

        vTaskDelay(pdMS_TO_TICKS(1000));
    }

    return -1;
}
Ejemplo n.º 2
0
static int sim800_pdp_open(struct cellular *modem, const char *apn)
{
    at_set_timeout(modem->at, SET_TIMEOUT);

    /* Configure and open context for FTP/HTTP applications. */
    at_command_simple(modem->at, "AT+SAPBR=3,1,APN,\"%s\"", apn);
    at_command(modem->at, "AT+SAPBR=1,1");

    /* Skip the configuration if context is already open. */
    if (sim800_ipstatus(modem) == 0)
        return 0;

    /* Commands below don't check the response. This is intentional; instead
     * of trying to stay in sync with the GPRS state machine we blindly issue
     * the command sequence needed to transition through all the states and
     * reach IP STATUS. See SIM800 Series_TCPIP_Application Note_V1.01.pdf for
     * the GPRS states documentation. */

    /* Configure context for TCP/IP applications. */
    at_command(modem->at, "AT+CSTT=\"%s\"", apn);
    /* Establish context. */
    at_command(modem->at, "AT+CIICR");
    /* Read local IP address. Switches modem to IP STATUS state. */
    at_set_command_scanner(modem->at, scanner_cifsr);
    at_command(modem->at, "AT+CIFSR");

    return sim800_ipstatus(modem);
}
Ejemplo n.º 3
0
static int telit2_socket_waitack(struct cellular *modem, int connid)
{
    const char *response;

    at_set_timeout(modem->at, 5);
    for (int i=0; i<TELIT2_WAITACK_TIMEOUT; i++) {
        /* Read number of bytes waiting. */
        int ack_waiting;
        response = at_command(modem->at, "AT#SI=%d", connid);
        at_simple_scanf(response, "#SI: %*d,%*d,%*d,%*d,%d", &ack_waiting);

        /* ack_waiting is meaningless if socket is not connected. Check this. */
        int socket_status;
        response = at_command(modem->at, "AT#SS=%d", connid);
        at_simple_scanf(response, "#SS: %*d,%d", &socket_status);
        if (socket_status == 0) {
            errno = ECONNRESET;
            return -1;
        }

        /* Return if all bytes were acknowledged. */
        if (ack_waiting == 0)
            return 0;

        sleep(1);
    }

    errno = ETIMEDOUT;
    return -1;
}
Ejemplo n.º 4
0
static int sim800_attach(struct cellular *modem)
{
    at_set_callbacks(modem->at, &sim800_callbacks, (void *) modem);

    at_set_timeout(modem->at, 2);

    /* Perform autobauding. */
    for (int i=0; i<SIM800_AUTOBAUD_ATTEMPTS; i++) {
        const char *response = at_command(modem->at, "AT");
        if (response != NULL)
            /* Modem replied. Good. */
            break;
    }

    /* Disable local echo. */
    at_command(modem->at, "ATE0");

    /* Disable local echo again; make sure it was disabled successfully. */
    at_command_simple(modem->at, "ATE0");

    /* Initialize modem. */
    static const char *const init_strings[] = {
//        "AT+IPR=0",                     /* Enable autobauding if not already enabled. */
        "AT+IFC=0,0",                   /* Disable hardware flow control. */
        "AT+CMEE=2",                    /* Enable extended error reporting. */
        "AT+CLTS=0",                    /* Don't sync RTC with network time, it's broken. */
        "AT+CIURC=0",                   /* Disable "Call Ready" URC. */
        "AT&W0",                        /* Save configuration. */
        "AT+BTSPPCFG=\"TT\",1",
        "AT+BTPAIRCFG=0",
        "AT+BTSPPGET=1",
        "AT+BTPOWER=1",
        NULL
    };
    for (const char *const *command=init_strings; *command; command++)
        at_command_simple(modem->at, "%s", *command);

    /* Configure IP application. */

//    /* Switch to multiple connections mode; it's less buggy. */
//    if (sim800_config(modem, "CIPMUX", "1", SIM800_CIPCFG_RETRIES) != 0)
//        return -1;
//    /* Receive data manually. */
//    if (sim800_config(modem, "CIPRXGET", "1", SIM800_CIPCFG_RETRIES) != 0)
//        return -1;
//    /* Enable quick send mode. */
//    if (sim800_config(modem, "CIPQSEND", "1", SIM800_CIPCFG_RETRIES) != 0)
//        return -1;

    return 0;
}
Ejemplo n.º 5
0
static void
grub_keyboard_controller_write (grub_uint8_t c)
{
  at_command (KEYBOARD_COMMAND_WRITE);
  keyboard_controller_wait_until_ready ();
  grub_outb (c, KEYBOARD_REG_DATA);
}
Ejemplo n.º 6
0
Archivo: tdm.c Proyecto: gfornax/SiK
// handle an incoming at command from the remote radio
static void
handle_at_command(__pdata uint8_t len)
{
	if (len < 2 || len > AT_CMD_MAXLEN || 
	    pbuf[0] != (uint8_t)'R' || 
	    pbuf[1] != (uint8_t)'T') {
		// assume its an AT command reply
		register uint8_t i;
		for (i=0; i<len; i++) {
			putchar(pbuf[i]);
		}
		return;
	}

	// setup the command in the at_cmd buffer
	memcpy(at_cmd, pbuf, len);
	at_cmd[len] = 0;
	at_cmd[0] = 'A'; // replace 'R'
	at_cmd_len = len;
	at_cmd_ready = true;

	// run the AT command, capturing any output to the packet
	// buffer
	// this reply buffer will be sent at the next opportunity
	printf_start_capture(pbuf, sizeof(pbuf));
	at_command();
	len = printf_end_capture();
	if (len > 0) {
		packet_inject(pbuf, len);
	}
}
Ejemplo n.º 7
0
static grub_uint8_t
grub_keyboard_controller_read (void)
{
  at_command (KEYBOARD_COMMAND_READ);
  keyboard_controller_wait_until_ready ();
  return grub_inb (KEYBOARD_REG_DATA);
}
Ejemplo n.º 8
0
static int telit2_attach(struct cellular *modem)
{
    at_set_callbacks(modem->at, &telit2_callbacks, (void *) modem);

    at_set_timeout(modem->at, 1);
    at_command(modem->at, "AT");        /* Aid autobauding. Always a good idea. */
    at_command(modem->at, "ATE0");      /* Disable local echo. */

    /* Initialize modem. */
    static const char *const init_strings[] = {
        "AT&K0",                        /* Disable hardware flow control. */
        "AT#SELINT=2",                  /* Set Telit module compatibility level. */
        "AT+CMEE=2",                    /* Enable extended error reporting. */
        NULL
    };
    for (const char *const *command=init_strings; *command; command++)
        at_command_simple(modem->at, "%s", *command);

    return 0;
}
Ejemplo n.º 9
0
int main(int argc, char *argv[])
{
	int fd;

	bdaddr_t bdaddr;
	uint8_t channel;

	switch (argc) {
	case 2:
		str2ba(argv[1], &bdaddr);
		channel = 1;
		break;
	case 3:
		str2ba(argv[1], &bdaddr);
		channel = atoi(argv[2]);
		break;
	default:
		usage();
		exit(-1);
	}

	if (bacmp(BDADDR_ANY, &bdaddr)) {
		printf("Connecting to %s on channel %d\n", argv[1], channel);
		fd = open_socket(&bdaddr, channel);
	} else {
		printf("Opening device %s\n", argv[1]);
		fd = open_device(argv[1]);
	}

	if (fd < 0)
		exit(-2);

	at_command(fd, "ATZ\r\n", 10000);
	at_command(fd, "AT+CPBS=\"ME\"\r\n", 10000);
	at_command(fd, "AT+CPBR=1,100\r\n", 100000);

	close(fd);

	return 0;
}
Ejemplo n.º 10
0
static int telit2_op_iccid(struct cellular *modem, char *buf, size_t len)
{
    char fmt[24];
    if (snprintf(fmt, sizeof(fmt), "#CCID: %%[0-9]%ds", (int) len) >= (int) sizeof(fmt)) {
        errno = ENOSPC;
        return -1;
    }

    at_set_timeout(modem->at, 5);
    const char *response = at_command(modem->at, "AT#CCID");
    at_simple_scanf(response, fmt, buf);
    buf[len-1] = '\0';

    return 0;
}
Ejemplo n.º 11
0
static void manager (struct uart * uart)

{
	if (_anyset (uart->flags, UART_WAKE))
	{
		at_wake (uart);
	}
	if (_anyset (uart->flags, UART_COMMAND))
	{
		at_command (uart);
	}
	if (_anyset (uart->flags, UART_ATBR))
	{
		atbr (uart);
	}
	return;
}
Ejemplo n.º 12
0
static int telit2_pdp_open(struct cellular *modem, const char *apn)
{
    at_set_timeout(modem->at, 5);
    at_command_simple(modem->at, "AT+CGDCONT=1,IP,\"%s\"", apn);

    at_set_timeout(modem->at, 150);
    const char *response = at_command(modem->at, "AT#SGACT=1,1");

    if (response == NULL)
        return -1;

    if (!strcmp(response, "+CME ERROR: context already activated"))
        return 0;

    int ip[4];
    at_simple_scanf(response, "#SGACT: %d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);

    return 0;
}
Ejemplo n.º 13
0
static ssize_t telit2_socket_recv(struct cellular *modem, int connid, void *buffer, size_t length, int flags)
{
    (void) flags;

    int cnt = 0;
    while (cnt < (int) length) {
        int chunk = (int) length - cnt;
        /* Limit read size to avoid overflowing AT response buffer. */
        if (chunk > 128)
            chunk = 128;

        /* Perform the read. */
        at_set_timeout(modem->at, 150);
        at_set_command_scanner(modem->at, scanner_srecv);
        const char *response = at_command(modem->at, "AT#SRECV=%d,%d", connid, chunk);
        if (response == NULL)
            return -1;

        /* Find the header line. */
        int bytes;
        at_simple_scanf(response, "#SRECV: %*d,%d", &bytes);

        /* Bail out if we're out of data. Message is misleading. */
        /* FIXME: We should maybe block until we receive something? */
        if (!strcmp(response, "+CME ERROR: activation failed"))
            break;

        /* Locate the payload. */
        const char *data = strchr(response, '\n');
        if (data == NULL) {
            errno = EPROTO;
            return -1;
        }
        data += 1;

        /* Copy payload to result buffer. */
        memcpy((char *)buffer + cnt, data, bytes);
        cnt += bytes;
    }

    return cnt;
}
Ejemplo n.º 14
0
static int sim800_ftp_getdata(struct cellular *modem, char *buffer, size_t length)
{
    struct cellular_sim800 *priv = (struct cellular_sim800 *) modem;

    int retries = 0;
retry:
    at_set_timeout(modem->at, SET_TIMEOUT);
    at_set_command_scanner(modem->at, scanner_ftpget2);
    const char *response = at_command(modem->at, "AT+FTPGET=2,%zu", length);

    if (response == NULL)
        return -1;

    int cnflength;
    if (sscanf(response, "+FTPGET: 2,%d", &cnflength) == 1) {
        /* Zero means no data is available. Wait for it. */
        if (cnflength == 0) {
            /* Bail out on timeout. */
            if (++retries >= SIM800_FTP_TIMEOUT) {
                return -1;
            }
            vTaskDelay(pdMS_TO_TICKS(1000));
            goto retry;
        }

        /* Locate the payload. */
        const char *data = strchr(response, '\n');
        if (data == NULL) {
            return -1;
        }
        data += 1;

        /* Copy payload to result buffer. */
        memcpy((char *)buffer, data, cnflength);
        return cnflength;
    } else if (priv->ftpget1_status == 0) {
        /* Transfer finished. */
        return 0;
    } else {
        return -1;
    }
}
Ejemplo n.º 15
0
/**
 * Retrieve AT+CIPSTATUS state.
 *
 * @returns Zero if context is open, -1 and sets errno otherwise.
 */
static int sim800_ipstatus(struct cellular *modem)
{
    at_set_timeout(modem->at, 10);
    at_set_command_scanner(modem->at, scanner_cipstatus);
    const char *response = at_command(modem->at, "AT+CIPSTATUS");

    if (response == NULL)
        return -1;

    const char *state = strstr(response, "STATE: ");
    if (!state) {
        return -1;
    }
    state += strlen("STATE: ");
    if (!strncmp(state, "IP STATUS", strlen("IP STATUS")))
        return 0;
    if (!strncmp(state, "IP PROCESSING", strlen("IP PROCESSING")))
        return 0;

    return -1;
}
Ejemplo n.º 16
0
static int sim800_socket_waitack(struct cellular *modem, int connid)
{
    const char *response;
    if(connid == SIM800_NSOCKETS) {
      return 0;
    } else if(connid < SIM800_NSOCKETS) {
      at_set_timeout(modem->at, 5);
      for (int i=0; i<SIM800_WAITACK_TIMEOUT; i++) {
          /* Read number of bytes waiting. */
          int nacklen;
          response = at_command(modem->at, "AT+CIPACK=%d", connid);
          at_simple_scanf(response, "+CIPACK: %*d,%*d,%d", &nacklen);

          /* Return if all bytes were acknowledged. */
          if (nacklen == 0)
              return 0;

          vTaskDelay(pdMS_TO_TICKS(1000));
      }
    }
    return -1;
}
Ejemplo n.º 17
0
int main(int argc, char *argv[])
{
    assert(argc-1 == 1);
    const char *devpath = argv[1];

    printf("allocating channel...\n");
    struct at *at = at_alloc_unix(devpath, B115200);

    printf("opening port...\n");
    assert(at_open(at) == 0);

    printf("attaching callbacks\n");
    at_set_callbacks(at, &generic_modem_callbacks, NULL);

    const char *commands[] = {
        "AT",
        "ATE0",
        "AT+CGMR",
        "AT+CGSN",
        "AT+CCID",
        "AT+CMEE=0",
        "AT+BLAH",
        "AT+CMEE=2",
        "AT+BLAH",
        NULL
    };

    printf("sending commands...\n");
    at_set_timeout(at, 10);
    for (const char **command=commands; *command; command++) {
        const char *result = at_command(at, *command);
        printf("%s => %s\n", *command, result ? result : strerror(errno));
    }

    printf("freeing resources...\n");
    at_free(at);

    return 0;
}
Ejemplo n.º 18
0
static int telit2_op_clock_gettime(struct cellular *modem, struct timespec *ts)
{
    struct tm tm;
    int offset;

    at_set_timeout(modem->at, 1);
    const char *response = at_command(modem->at, "AT+CCLK?");
    memset(&tm, 0, sizeof(struct tm));
    at_simple_scanf(response, "+CCLK: \"%d/%d/%d,%d:%d:%d%d\"",
            &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
            &tm.tm_hour, &tm.tm_min, &tm.tm_sec,
            &offset);

    /* Most modems report some starting date way in the past when they have
     * no date/time estimation. */
    if (tm.tm_year < 14) {
        errno = EINVAL;
        return 1;
    }

    /* Adjust values and perform conversion. */
    tm.tm_year += 2000 - 1900;
    tm.tm_mon -= 1;
    time_t unix_time = timegm(&tm);
    if (unix_time == -1) {
        errno = EINVAL;
        return -1;
    }

    /* Telit modems return local date/time instead of UTC (as defined in 3GPP
     * 27.007). Remove the timezone shift. */
    unix_time -= 15*60*offset;

    /* All good. Return the result. */
    ts->tv_sec = unix_time;
    ts->tv_nsec = 0;
    return 0;
}
Ejemplo n.º 19
0
int main(int argc, char *argv[])
{
	int fd;
        
	bdaddr_t bdaddr;
	uint8_t channel;

	char *atcmd;
	char prompt[]="at> ";
        int hci_nr = 0;

	switch (argc) {
	case 2:
	  str2ba(argv[1], &bdaddr);
	  channel = 1;
	  break;
	case 3:
	  str2ba(argv[1], &bdaddr);
	  channel = atoi(argv[2]);
	  break;
	case 4:
	  str2ba(argv[1], &bdaddr);
	  channel = atoi(argv[2]);
	  hci_nr = atoi(argv[3]);
	  break;
	default:
	  usage();
	  exit(-1);
	}

	if (bacmp(BDADDR_ANY, &bdaddr)) {
		printf("Connecting to %s on channel %d\n", argv[1], channel);
		fd = open_socket(&bdaddr, channel, hci_nr);
	} else {
		printf("Opening device %s\n", argv[1]);
		fd = open_device(argv[1]);
	}

	if (fd < 0)
		exit(-2);

	at_command(fd, "ATZ\r\n", 10000);

	while(1)
	  {
	    atcmd = readline(prompt);

	    if((!strcmp(atcmd,"exit")) || (!strcmp(atcmd,"quit")))
	      {
		close(fd);
		exit(0);
	      }
	    else
	      {
		strcat(atcmd,"\r\n");
		at_command(fd, atcmd, 100000);
	      }
	  }

	close(fd);
	return 0;
}
Ejemplo n.º 20
0
static ssize_t sim800_socket_recv(struct cellular *modem, int connid, void *buffer, size_t length, int flags)
{
    struct cellular_sim800 *priv = (struct cellular_sim800 *) modem;
    (void) flags;

    int cnt = 0;
    // TODO its dumb and exceptions should be handled in other right way
    // FIXME: It has to be changed. Leave for now
    if(connid == SIM800_NSOCKETS) {
      if(priv->spp_status != SIM800_SOCKET_STATUS_CONNECTED) {
        return -1;
      }

      /* Copy payload to result buffer. */
      cnt = strlen(spp_recv_buf);
      if(cnt) {
          memcpy(buffer, spp_recv_buf, cnt);
          *(((char*)buffer) + cnt) = '\0';
          spp_recv_buf[0] = '\0';
      }
    }
    else if(connid < SIM800_NSOCKETS) {
      if(priv->socket_status[connid] != SIM800_SOCKET_STATUS_CONNECTED) {
        return -1;
      }
      char tries = 4;
      while ( (cnt < (int) length) && tries-- ){
          int chunk = (int) length - cnt;
          /* Limit read size to avoid overflowing AT response buffer. */
          chunk = chunk > 480 ? 480 : chunk;

          /* Perform the read. */
          at_set_timeout(modem->at, SET_TIMEOUT);
          at_set_command_scanner(modem->at, scanner_ciprxget);
          const char *response = at_command(modem->at, "AT+CIPRXGET=2,%d,%d", connid, chunk);
          if (response == NULL)
              return -1;

          /* Find the header line. */
          int requested, confirmed;
          // TODO:
          // 1. connid is not checked
          // 2. there is possible a bug here. if not all data are ready (confirmed < requested)
          // then wierd things can happen. see memcpy
          // requested should be equal to chunk
          // confirmed is that what can be read
          at_simple_scanf(response, "+CIPRXGET: 2,%*d,%d,%d", &requested, &confirmed);

          /* Bail out if we're out of data. */
          /* FIXME: We should maybe block until we receive something? */
          if (confirmed == 0)
              break;

          /* Locate the payload. */
          /* TODO: what if no \n is in input stream?
           * should use strnchr at least */
          const char *data = strchr(response, '\n');
          if (data++ == NULL) {
              return -1;
          }

          /* Copy payload to result buffer. */
          memcpy((char *)buffer + cnt, data, confirmed);
          cnt += confirmed;
      }
    }

    return cnt;
}
Ejemplo n.º 21
0
Archivo: tdm.c Proyecto: gfornax/SiK
/// main loop for time division multiplexing transparent serial
///
void
tdm_serial_loop(void)
{
	__pdata uint16_t last_t = timer2_tick();
	__pdata uint16_t last_link_update = last_t;

	_canary = 42;

	for (;;) {
		__pdata uint8_t	len;
		__pdata uint16_t tnow, tdelta;
		__pdata uint8_t max_xmit;

		if (_canary != 42) {
			panic("stack blown\n");
		}

		if (pdata_canary != 0x41) {
			panic("pdata canary changed\n");
		}

		// give the AT command processor a chance to handle a command
		at_command();

		// display test data if needed
		if (test_display) {
			display_test_output();
			test_display = 0;
		}

		if (seen_mavlink && feature_mavlink_framing && !at_mode_active) {
			seen_mavlink = false;
			MAVLink_report();
		}

		// set right receive channel
		radio_set_channel(fhop_receive_channel());

		// get the time before we check for a packet coming in
		tnow = timer2_tick();

		// see if we have received a packet
		if (radio_receive_packet(&len, pbuf)) {

			// update the activity indication
			received_packet = true;
			fhop_set_locked(true);
			
			// update filtered RSSI value and packet stats
			statistics.average_rssi = (radio_last_rssi() + 7*(uint16_t)statistics.average_rssi)/8;
			statistics.receive_count++;
			
			// we're not waiting for a preamble
			// any more
			transmit_wait = 0;

			if (len < 2) {
				// not a valid packet. We always send
				// two control bytes at the end of every packet
				continue;
			}

			// extract control bytes from end of packet
			memcpy(&trailer, &pbuf[len-sizeof(trailer)], sizeof(trailer));
			len -= sizeof(trailer);

			if (trailer.window == 0 && len != 0) {
				// its a control packet
				if (len == sizeof(struct statistics)) {
					memcpy(&remote_statistics, pbuf, len);
				}

				// don't count control packets in the stats
				statistics.receive_count--;
			} else if (trailer.window != 0) {
				// sync our transmit windows based on
				// received header
				sync_tx_windows(len);
				last_t = tnow;

				if (trailer.command == 1) {
					handle_at_command(len);
				} else if (len != 0 && 
					   !packet_is_duplicate(len, pbuf, trailer.resend) &&
					   !at_mode_active) {
					// its user data - send it out
					// the serial port
					//printf("rcv(%d,[", len);
					LED_ACTIVITY = LED_ON;
					serial_write_buf(pbuf, len);
					LED_ACTIVITY = LED_OFF;
					//printf("]\n");
				}
			}
			continue;
		}

		// see how many 16usec ticks have passed and update
		// the tdm state machine. We re-fetch tnow as a bad
		// packet could have cost us a lot of time.
		tnow = timer2_tick();
		tdelta = tnow - last_t;
		tdm_state_update(tdelta);
		last_t = tnow;

		// update link status every 0.5s
		if (tnow - last_link_update > 32768) {
			link_update();
			last_link_update = tnow;
		}

		if (lbt_rssi != 0) {
			// implement listen before talk
			if (radio_current_rssi() < lbt_rssi) {
				lbt_listen_time += tdelta;
			} else {
				lbt_listen_time = 0;
				if (lbt_rand == 0) {
					lbt_rand = ((uint16_t)rand()) % lbt_min_time;
				}
			}
			if (lbt_listen_time < lbt_min_time + lbt_rand) {
				// we need to listen some more
				continue;
			}
		}

		// we are allowed to transmit in our transmit window
		// or in the other radios transmit window if we have
		// bonus ticks
#if USE_TICK_YIELD
		if (tdm_state != TDM_TRANSMIT &&
		    !(bonus_transmit && tdm_state == TDM_RECEIVE)) {
			// we cannot transmit now
			continue;
		}
#else
		if (tdm_state != TDM_TRANSMIT) {
			continue;
		}		
#endif

		if (transmit_yield != 0) {
			// we've give up our window
			continue;
		}

		if (transmit_wait != 0) {
			// we're waiting for a preamble to turn into a packet
			continue;
		}

		if (!received_packet &&
		    radio_preamble_detected() ||
		    radio_receive_in_progress()) {
			// a preamble has been detected. Don't
			// transmit for a while
			transmit_wait = packet_latency;
			continue;
		}

		// sample the background noise when it is out turn to
		// transmit, but we are not transmitting,
		// averaged over around 4 samples
		statistics.average_noise = (radio_current_rssi() + 3*(uint16_t)statistics.average_noise)/4;

		if (duty_cycle_wait) {
			// we're waiting for our duty cycle to drop
			continue;
		}

		// how many bytes could we transmit in the time we
		// have left?
		if (tdm_state_remaining < packet_latency) {
			// none ....
			continue;
		}
		max_xmit = (tdm_state_remaining - packet_latency) / ticks_per_byte;
		if (max_xmit < PACKET_OVERHEAD) {
			// can't fit the trailer in with a byte to spare
			continue;
		}
		max_xmit -= PACKET_OVERHEAD;
		if (max_xmit > max_data_packet_length) {
			max_xmit = max_data_packet_length;
		}

		// ask the packet system for the next packet to send
		if (send_at_command && 
		    max_xmit >= strlen(remote_at_cmd)) {
			// send a remote AT command
			len = strlen(remote_at_cmd);
			memcpy(pbuf, remote_at_cmd, len);
			trailer.command = 1;
			send_at_command = false;
		} else {
			// get a packet from the serial port
			memset(pbuf, 0x40, 16);
			len = packet_get_next(max_xmit-16, pbuf+16) + 16;
			trailer.command = packet_is_injected();
			if (len == 16)
				len = 0;
		}

		if (len > max_data_packet_length) {
			panic("oversized tdm packet");
		}

		trailer.bonus = (tdm_state == TDM_RECEIVE);
		trailer.resend = packet_is_resend();

		if (tdm_state == TDM_TRANSMIT &&
		    len == 0 && 
		    send_statistics && 
		    max_xmit >= sizeof(statistics)) {
			// send a statistics packet
			send_statistics = 0;
			memcpy(pbuf, &statistics, sizeof(statistics));
			len = sizeof(statistics);
		
			// mark a stats packet with a zero window
			trailer.window = 0;
			trailer.resend = 0;
		} else {
			// calculate the control word as the number of
			// 16usec ticks that will be left in this
			// tdm state after this packet is transmitted
			trailer.window = (uint16_t)(tdm_state_remaining - flight_time_estimate(len+sizeof(trailer)));
		}

		// set right transmit channel
		radio_set_channel(fhop_transmit_channel());

		memcpy(&pbuf[len], &trailer, sizeof(trailer));

		if (len != 0 && trailer.window != 0) {
			// show the user that we're sending real data
			LED_ACTIVITY = LED_ON;
		}

		if (len == 0) {
			// sending a zero byte packet gives up
			// our window, but doesn't change the
			// start of the next window
			transmit_yield = 1;
		}

		// after sending a packet leave a bit of time before
		// sending the next one. The receivers don't cope well
		// with back to back packets
		transmit_wait = packet_latency;

		// if we're implementing a duty cycle, add the
		// transmit time to the number of ticks we've been transmitting
		if ((duty_cycle - duty_cycle_offset) != 100) {
			transmitted_ticks += flight_time_estimate(len+sizeof(trailer));
		}

		// start transmitting the packet
		if (!radio_transmit(len + sizeof(trailer), pbuf, tdm_state_remaining + (silence_period/2)) &&
		    len != 0 && trailer.window != 0 && trailer.command == 0) {
			packet_force_resend();
		}

		if (lbt_rssi != 0) {
			// reset the LBT listen time
			lbt_listen_time = 0;
			lbt_rand = 0;
		}

		// set right receive channel
		radio_set_channel(fhop_receive_channel());

		// re-enable the receiver
		radio_receiver_on();

		if (len != 0 && trailer.window != 0) {
			LED_ACTIVITY = LED_OFF;
		}
	}
}
Ejemplo n.º 22
0
/*!
 * \brief Sequentially initializes the modem step-by-step
 */
void BridgeCommunicator::initBridgeModem()
{
    QByteArray at_command(1, '\r');

    switch (_currentInitStep) {
    case IBMS_UnInitialized:
        Q_EMIT snlProcessingStarted(IBMS_ReadyToUse, tr("Initializing modem...")); // show the progress dialog
        at_command.prepend("ATE0");
        _timerModemInitNotResponse.start(1000);
        break;

    case IBMS_ATE0:
        _bReconnect = false;
        at_command.prepend("ATI");
        break;

    case IBMS_ATI:
        at_command.prepend("AT+CGATT=1");
        break;

    case IBMS_CGATT:
        at_command.prepend("AT+CIPCSGP=1,\"vpnl.kyivstar.net\",\"1\",\"1\"");
        break;

    case IBMS_CIPCSGP:
//        at_command.prepend("AT+CDNSORIP=0"); // WARNING: this string for SIM-300 ONLY
        at_command.prepend("AT");   // this string for SIM-900 (skip current step)
        break;

    case IBMS_CDNSORIP:
        at_command.prepend("AT+CIPMODE=1");
        break;

    case IBMS_CIPMODE:
        /*  +CIPCCFG: <NmRetry>,<WaitTm * 200 ms>,<SendSz>,<esc>
            +CIPCCFG: <3-8>,<2-10>,<256-1024>,<0,1>     */
        at_command.prepend("AT+CIPCCFG=5,6,1024,1");
        break;

    case IBMS_CIPCCFG:
        at_command.prepend( QString("AT+CIPSTART=\"UDP\",\"%1\",\"%2\"")
                                .arg(_mw->currentChannelSettings().deviceIp)
                                .arg(_mw->currentChannelSettings().devicePort)
                                .toLatin1()
                           );
        break;

    case IBMS_WaitForConnect:
        _timerModemInitNotResponse.start(20000);
        return;

    default:
        return; // modem initialization finished
    }

    sendThroughConcreteChannel(at_command);
    addToLog(at_command, tr("Send: "), tr("[ AT-command ]"), Qt::green);
    Q_EMIT snlTxData();

    if (IBMS_UnInitialized != _currentInitStep)
        _timerModemInitNotResponse.start(10000);
}
Ejemplo n.º 23
0
static int telit2_ftp_getdata(struct cellular *modem, char *buffer, size_t length)
{
    /* FIXME: This function's flow is really ugly. */
    int retries = 0;
retry:
    at_set_timeout(modem->at, 150);
    at_set_command_scanner(modem->at, scanner_ftprecv);
    const char *response = at_command(modem->at, "AT#FTPRECV=%zu", length);

    if (response == NULL)
        return -1;

    int bytes;
    if (sscanf(response, "#FTPRECV: %d", &bytes) == 1) {
        /* Zero means no data is available. Wait for it. */
        if (bytes == 0) {
            /* Bail out on timeout. */
            if (++retries >= TELIT2_FTP_TIMEOUT) {
                errno = ETIMEDOUT;
                return -1;
            }
            sleep(1);
            goto retry;
        }

        /* Locate the payload. */
        const char *data = strchr(response, '\n');
        if (data == NULL) {
            errno = EPROTO;
            return -1;
        }
        data += 1;

        /* Copy payload to result buffer. */
        memcpy(buffer, data, bytes);
        return bytes;
    }

    /* Error or EOF? */
    int eof;
    response = at_command(modem->at, "AT#FTPGETPKT?");
    /* Expected response: #FTPGETPKT: <remotefile>,<viewMode>,<eof> */
#if 0
    /* The %[] specifier is not supported on some embedded systems. */
    at_simple_scanf(response, "#FTPGETPKT: %*[^,],%*d,%d", &eof);
#else
    /* Parse manually. */
    if (response == NULL)
        return -1;
    errno = EPROTO;
    /* Check the initial part of the response. */
    if (strncmp(response, "#FTPGETPKT: ", 12))
        return -1;
    /* Skip the filename. */
    response = strchr(response, ',');
    if (response == NULL)
        return -1;
    response++;
    at_simple_scanf(response, "%*d,%d", &eof);
#endif

    if (eof == 1)
        return 0;

    return -1;
}