#include #include #include #include "eos.h" #include "event.h" #include "dev/net.h" #include "cell.h" static eos_evt_handler_t evt_handler[EOS_CELL_MAX_MTYPE]; static void cell_handle_msg(unsigned char type, EOSMessage *msg, uint16_t len) { unsigned char mtype; unsigned char idx; if ((msg == NULL) || (len < 1)) { eos_net_bad_handler(type, msg, len); return; } mtype = msg->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, msg, len); } else { eos_net_bad_handler(type, msg, 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_status_parse(EOSMessage *msg, uint16_t len, uint8_t *status, uint8_t *connected) { unsigned char *buffer = msg->buffer; if (len < 2) return EOS_ERR_SIZE; if (buffer[0] != (EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS)) return EOS_ERR_NET; buffer++; len--; *status = buffer[0]; buffer++; len--; 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, EOSMessage *msg) { unsigned char type; uint16_t len; int rv; if (msg->size < 1) return EOS_ERR_SIZE; type = EOS_NET_MTYPE_CELL; len = 1; msg->buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS; rv = eos_net_xchg(&type, msg, &len); if (rv) return rv; if (type != EOS_NET_MTYPE_CELL) return EOS_ERR_NET; return eos_cell_status_parse(msg, len, status, connected); } int eos_cell_uart_take(EOSMessage *msg) { if (msg->size < 1) return EOS_ERR_SIZE; msg->buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_TAKE; return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); } int eos_cell_uart_give(EOSMessage *msg) { if (msg->size < 1) return EOS_ERR_SIZE; msg->buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_GIVE; return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); } unsigned char *eos_cell_uart_msg2data(EOSMessage *msg, uint16_t *len, uint16_t *size) { if (len && (*len < 1)) return NULL; if (msg->size < 1) return NULL; if (len && (msg->buffer[0] != (EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA))) return NULL; if (len) *len -= 1; if (size) *size = msg->size - 1; return msg->buffer + 1; } int eos_cell_uart_send(EOSMessage *msg, uint16_t len) { msg->buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA; return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, len + 1); } int eos_cell_uart_send_async(EOSMessage *msg, uint16_t len, int more) { msg->buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_UART_DATA; return eos_net_send(EOS_NET_MTYPE_CELL, msg, len + 1, more); } int eos_cell_voice_dial(char *num, EOSMessage *msg) { int async; size_t num_len; num_len = strlen(num); if (num_len > EOS_CELL_SIZE_PHNUM) return EOS_ERR_SIZE; if (msg->size < 1 + num_len) return EOS_ERR_SIZE; msg->buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_DIAL; memcpy(msg->buffer + 1, num, num_len); return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1 + num_len); } int eos_cell_voice_answer(EOSMessage *msg) { if (msg->size < 1) return EOS_ERR_SIZE; msg->buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_ANSWER; return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); } int eos_cell_voice_hangup(EOSMessage *msg) { if (msg->size < 1) return EOS_ERR_SIZE; msg->buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_HANGUP; return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); } unsigned char *eos_cell_voice_msg2pcm(EOSMessage *msg, uint16_t *len, uint16_t *size) { if (len && (*len < 1)) return NULL; if (msg->size < 1) return NULL; if (len && (msg->buffer[0] != (EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM))) return NULL; if (len) *len -= 1; if (size) *size = msg->size - 1; return msg->buffer + 1; } int eos_cell_voice_pcm_send(EOSMessage *msg, uint16_t len) { msg->buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, len + 1); } int eos_cell_voice_pcm_send_async(EOSMessage *msg, uint16_t len, int more) { msg->buffer[0] = EOS_CELL_MTYPE_VOICE | EOS_CELL_MTYPE_VOICE_PCM; return eos_net_send(EOS_NET_MTYPE_CELL, msg, len + 1, more); } int eos_cell_sms_send(char *addr, char *txt, EOSMessage *msg) { unsigned char *buffer = msg->buffer; size_t addr_len, txt_len; uint16_t len; addr_len = strlen(addr); txt_len = strlen(txt); if (addr_len > EOS_CELL_SMS_SIZE_ADDR) return EOS_ERR_SIZE; if (txt_len > EOS_CELL_SMS_SIZE_TXT) return EOS_ERR_SIZE; if (msg->size < 5) return EOS_ERR_SIZE; buffer[0] = EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG; buffer[1] = 0; buffer[2] = 0; if (*addr == '+') { buffer[3] = EOS_CELL_SMS_ADDRTYPE_INTL; addr++; addr_len--; } else { buffer[3] = EOS_CELL_SMS_ADDRTYPE_OTHER; } buffer[4] = addr_len; buffer += 5; len = 5; if (msg->size < 5 + addr_len + txt_len) return EOS_ERR_SIZE; memcpy(buffer, addr, addr_len); buffer += addr_len; len += addr_len; memcpy(buffer, txt, txt_len); buffer += txt_len; len += txt_len; return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, len); } int _eos_cell_sms_parse(EOSMessage *msg, uint16_t len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len) { unsigned char *buffer = msg->buffer; uint16_t _addr_len; if (len < 4 + EOS_CELL_SMS_SIZE_TS) return EOS_ERR_SIZE; if (buffer[0] != (EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG)) return EOS_ERR_NET; buffer += 3 + EOS_CELL_SMS_SIZE_TS; len -= 3 + EOS_CELL_SMS_SIZE_TS; _addr_len = *buffer; if (_addr_len > EOS_CELL_SMS_SIZE_ADDR) return EOS_ERR_SIZE; if ((_addr_len == 0) || (len < (_addr_len + 1))) return EOS_ERR_SIZE; if (addr && addr_len) { *addr = buffer + 1; *addr_len = _addr_len; } buffer += _addr_len + 1; len -= _addr_len + 1; if (len > EOS_CELL_SMS_SIZE_TXT) return EOS_ERR_SIZE; if (txt && txt_len) { *txt = buffer; *txt_len = len; } return EOS_OK; } int eos_cell_sms_parse(EOSMessage *msg, uint16_t len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size) { char *_addr, *_txt; uint16_t _addr_len, _txt_len; int rv; rv = _eos_cell_sms_parse(msg, len, &_addr, &_addr_len, &_txt, &_txt_len); if (rv) return rv; if (addr_size < _addr_len + 1) return EOS_ERR_SIZE; if (txt_size < _txt_len + 1) return EOS_ERR_SIZE; memcpy(addr, _addr, _addr_len); addr[_addr_len] = '\0'; memcpy(txt, _txt, _txt_len); txt[_txt_len] = '\0'; return EOS_OK; } char *eos_cell_sms_msg2txt(EOSMessage *msg, uint16_t *len) { char *txt; uint16_t txt_len; int rv; rv = _eos_cell_sms_parse(msg, *len, NULL, NULL, &txt, &txt_len); if (rv) return NULL; *len = txt_len; return txt; } int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, EOSMessage *msg) { unsigned char type; uint16_t len; int rv; if (msg->size < 1) return EOS_ERR_SIZE; type = EOS_NET_MTYPE_CELL; len = 1; msg->buffer[0] = EOS_CELL_MTYPE_PDP | atype; rv = eos_net_xchg(&type, msg, &len); if (rv) return rv; if ((type != EOS_NET_MTYPE_CELL) || (len < 1) || (msg->buffer[0] != EOS_CELL_MTYPE_PDP | atype)) return EOS_ERR_NET; len--; if ((len > EOS_CELL_PDP_SIZE_ARG) || (len > arg_size - 1)) return EOS_ERR_SIZE; memcpy(msg->buffer + 1, arg, len); arg[len] = '\0'; return EOS_OK; } int eos_cell_pdp_set(unsigned char atype, char *arg, EOSMessage *msg) { size_t arg_len; arg_len = strlen(arg); if (arg_len > EOS_CELL_PDP_SIZE_ARG) return EOS_ERR_SIZE; if (msg->size < 1 + arg_len) return EOS_ERR_SIZE; msg->buffer[0] = EOS_CELL_MTYPE_PDP | atype; memcpy(msg->buffer + 1, arg, arg_len); return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1 + arg_len); } int eos_cell_pdp_get_apn(char *apn, uint16_t apn_size, EOSMessage *msg) { return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_APN, apn, apn_size, msg); } int eos_cell_pdp_set_apn(char *apn, EOSMessage *msg) { return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_APN, apn, msg); } int eos_cell_pdp_get_usr(char *usr, uint16_t usr_size, EOSMessage *msg) { return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_USR, usr, usr_size, msg); } int eos_cell_pdp_set_usr(char *usr, EOSMessage *msg) { return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_USR, usr, msg); } int eos_cell_pdp_get_pwd(char *pwd, uint16_t pwd_size, EOSMessage *msg) { return eos_cell_pdp_get(EOS_CELL_MTYPE_PDP_GET_PWD, pwd, pwd_size, msg); } int eos_cell_pdp_set_pwd(char *pwd, EOSMessage *msg) { return eos_cell_pdp_set(EOS_CELL_MTYPE_PDP_SET_PWD, pwd, msg); } int eos_cell_pdp_connect(EOSMessage *msg) { if (msg->size < 1) return EOS_ERR_SIZE; msg->buffer[0] = EOS_CELL_MTYPE_PDP | EOS_CELL_MTYPE_PDP_CONNECT; return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); } int eos_cell_pdp_disconnect(EOSMessage *msg) { if (msg->size < 1) return EOS_ERR_SIZE; msg->buffer[0] = EOS_CELL_MTYPE_PDP | EOS_CELL_MTYPE_PDP_DISCONNECT; return eos_net_send_sync(EOS_NET_MTYPE_CELL, msg, 1); }