#include #include #include #include "eos.h" #include "event.h" #include "dev/net.h" #include "cell.h" #define GSM_TS_SIZE 25 static eos_evt_handler_t evt_handler[EOS_CELL_MAX_MTYPE]; static void cell_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { unsigned char mtype; unsigned char idx; if ((buffer == NULL) || (len < 1)) { eos_net_bad_handler(type, buffer, len); return; } mtype = buffer[0]; idx = (mtype & EOS_CELL_MTYPE_MASK) >> 4; if ((idx < EOS_CELL_MAX_MTYPE) && evt_handler[idx]) { evt_handler[idx](mtype & ~EOS_CELL_MTYPE_MASK, buffer, len); } else { eos_net_bad_handler(type, buffer, len); } } void eos_cell_init(void) { int i; for (i=0; i> 4; if (idx < EOS_CELL_MAX_MTYPE) evt_handler[idx] = handler; } eos_evt_handler_t eos_cell_get_handler(unsigned char mtype) { unsigned char idx = (mtype & EOS_CELL_MTYPE_MASK) >> 4; if (idx < EOS_CELL_MAX_MTYPE) return evt_handler[idx]; return NULL; } int eos_cell_send_buffer(unsigned char *buffer, uint16_t buf_len, uint16_t offset, int sync) { buffer -= offset; return eos_net_send_async(EOS_NET_MTYPE_CELL, buffer, buf_len + offset, 1); } int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t *connected) { if (len < 2) return EOS_ERR_SIZE; if (buffer[0] != (EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS)) return EOS_ERR_NET; buffer++; len -= 1; *status = buffer[0]; buffer++; len -= 1; if (*status == EOS_CELL_STATUS_PPP) { if (len < 1) return EOS_ERR_SIZE; if (connected) *connected = buffer[0]; buffer++; len--; } return EOS_OK; } int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer) { unsigned char type; uint16_t len; int do_release; int rv; do_release = 0; if (buffer == NULL) { buffer = eos_net_alloc(); do_release = 1; } type = EOS_NET_MTYPE_CELL; len = 1; buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS; rv = eos_net_xchg(&type, buffer, &len); if (rv) goto cell_status_fin; if (type != EOS_NET_MTYPE_CELL) { rv = EOS_ERR_NET; goto cell_status_fin; } rv = eos_cell_status_parse(buffer, len, status, connected); cell_status_fin: if (do_release) eos_net_free(buffer, 1); return rv; } int eos_cell_uart_take(unsigned char *buffer, int sync) { int async; if (buffer == NULL) { buffer = eos_net_alloc(); async = 1; } else { async = !sync; } buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_TAKE; return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); } int eos_cell_uart_give(unsigned char *buffer, int sync) { int async; if (buffer == NULL) { buffer = eos_net_alloc(); async = 1; } else { async = !sync; } buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_GIVE; return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); } unsigned char *eos_cell_uart_data_buffer(uint16_t *offset) { unsigned char *buffer; buffer = eos_net_alloc(); buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA; *offset = 1; return buffer + *offset; } int eos_cell_voice_dial(char *num, unsigned char *buffer, int sync) { int async; size_t num_len; num_len = strlen(num); if (num_len > EOS_CELL_MAX_DIAL_STR) return EOS_ERR_SIZE; if (buffer == NULL) { buffer = eos_net_alloc(); async = 1; } else { async = !sync; } buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_DIAL; strcpy(buffer + 1, num); return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1 + num_len, async, 1); } int eos_cell_voice_answer(unsigned char *buffer, int sync) { int async; if (buffer == NULL) { buffer = eos_net_alloc(); async = 1; } else { async = !sync; } buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_ANSWER; return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); } int eos_cell_voice_hangup(unsigned char *buffer, int sync) { int async; if (buffer == NULL) { buffer = eos_net_alloc(); async = 1; } else { async = !sync; } buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_HANGUP; return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); } unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset) { unsigned char *buffer; buffer = eos_net_alloc(); buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; *offset = 1; return buffer + *offset; } int eos_cell_sms_send(char *num, char *text, unsigned char *buffer, int sync) { int async; size_t num_len, text_len; uint16_t len; num_len = strlen(num); text_len = strlen(text); if (num_len > EOS_CELL_MAX_DIAL_STR) return EOS_ERR_SIZE; if (text_len > EOS_CELL_MAX_SMS_TEXT) return EOS_ERR_SIZE; if (buffer == NULL) { buffer = eos_net_alloc(); async = 1; } else { async = !sync; } buffer[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG; buffer[1] = (*num == '+' ? EOS_CELL_SMS_ADDRTYPE_INTL : EOS_CELL_SMS_ADDRTYPE_OTHER); buffer[2] = num_len; len = 3; strcpy(buffer + len, num); len += num_len; strcpy(buffer + len, text); len += text_len; return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, len, async, 1); } int eos_cell_sms_recv(unsigned char *buffer, uint16_t len, char *num, uint16_t num_size, char *text, uint16_t text_size) { char *_num, *_text; uint16_t _num_len, _text_len; int rv; rv = eos_cell_sms_parse(buffer, len, &_num, &_num_len, &_text, &_text_len); if (rv) return rv; if (num_size < _num_len + 1) return EOS_ERR_SIZE; if (text_size < _text_len + 1) return EOS_ERR_SIZE; memcpy(num, _num, _num_len); num[_num_len] = '\0'; memcpy(text, _text, _text_len); text[_text_len] = '\0'; return EOS_OK; } int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **num, uint16_t *num_len, char **text, uint16_t *text_len) { uint16_t _num_len; if (len < 4 + GSM_TS_SIZE) return EOS_ERR_SIZE; if (buffer[0] != (EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG)) return EOS_ERR_NET; buffer += 3 + GSM_TS_SIZE; len -= 3 + GSM_TS_SIZE; _num_len = *buffer; if (_num_len > EOS_CELL_MAX_DIAL_STR) return EOS_ERR_SIZE; if ((_num_len == 0) || (len < (_num_len + 1))) return EOS_ERR_SIZE; if (num && num_len) { *num = buffer + 1; *num_len = _num_len; } buffer += _num_len + 1; len -= _num_len + 1; if (len > EOS_CELL_MAX_SMS_TEXT) return EOS_ERR_SIZE; if (text && text_len) { *text = buffer; *text_len = len; } return EOS_OK; }