📄 at-emulator.c
字号:
default: gn_atem_modem_result(MR_ERROR); return; } break; default: gn_atem_modem_result(MR_ERROR); return; } } gn_atem_modem_result(MR_OK);}static void gn_atem_sms_print(char *line, gn_sms *message, int mode){ switch (mode) { case INTERACT_MODE: gsprintf(line, MAX_LINE_LENGTH, _("\n\rDate/time: %d/%d/%d %d:%02d:%02d Sender: %s Msg Center: %s\n\rText: %s\n\r"), message->time.day, message->time.month, message->time.year, message->time.hour, message->time.minute, message->time.second, message->remote.number, message->smsc.number, message->user_data[0].u.text); break; case TEXT_MODE: if ((message->dcs.type == GN_SMS_DCS_GeneralDataCoding) && (message->dcs.u.general.alphabet == GN_SMS_DCS_8bit)) gsprintf(line, MAX_LINE_LENGTH, _("\"%s\",\"%s\",,\"%02d/%02d/%02d,%02d:%02d:%02d+%02d\"\n\r%s"), (message->status ? _("REC READ") : _("REC UNREAD")), message->remote.number, message->time.year, message->time.month, message->time.day, message->time.hour, message->time.minute, message->time.second, message->time.timezone, _("<Not implemented>")); else gsprintf(line, MAX_LINE_LENGTH, _("\"%s\",\"%s\",,\"%02d/%02d/%02d,%02d:%02d:%02d+%02d\"\n\r%s"), (message->status ? _("REC READ") : _("REC UNREAD")), message->remote.number, message->time.year, message->time.month, message->time.day, message->time.hour, message->time.minute, message->time.second, message->time.timezone, message->user_data[0].u.text); break; case PDU_MODE: gsprintf(line, MAX_LINE_LENGTH, _("<Not implemented>")); break; default: gsprintf(line, MAX_LINE_LENGTH, _("<Unknown mode>")); break; }}static void gn_atem_sms_handle(){ gn_error error; char buffer[MAX_LINE_LENGTH]; data.sms->memory_type = SMSType; data.sms->number = SMSNumber; error = gn_sms_get(&data, sm); switch (error) { case GN_ERR_NONE: gn_atem_sms_print(buffer, data.sms, INTERACT_MODE); gn_atem_string_out(buffer); break; default: gsprintf(buffer, MAX_LINE_LENGTH, _("\n\rNo message under number %d\n\r"), SMSNumber); gn_atem_string_out(buffer); break; } return;}/* Parser for SMS interactive mode */void gn_atem_sms_parse(char *buff){ if (!strcasecmp(buff, "HELP")) { gn_atem_string_out(_("\n\rThe following commands work...\n\r")); gn_atem_string_out("DIR\n\r"); gn_atem_string_out("EXIT\n\r"); gn_atem_string_out("HELP\n\r"); return; } if (!strcasecmp(buff, "DIR")) { SMSNumber = 1; gn_atem_sms_handle(); Parser = gn_atem_dir_parse; return; } if (!strcasecmp(buff, "EXIT")) { Parser = gn_atem_at_parse; gn_atem_modem_result(MR_OK); return; } gn_atem_modem_result(MR_ERROR);}/* Parser for DIR sub mode of SMS interactive mode. */void gn_atem_dir_parse(char *buff){ switch (toupper(*buff)) { case 'P': SMSNumber--; gn_atem_sms_handle(); return; case 'N': SMSNumber++; gn_atem_sms_handle(); return; case 'D': data.sms->memory_type = SMSType; data.sms->number = SMSNumber; if (gn_sm_functions(GN_OP_DeleteSMS, &data, sm) == GN_ERR_NONE) { gn_atem_modem_result(MR_OK); } else { gn_atem_modem_result(MR_ERROR); } return; case 'Q': Parser= gn_atem_sms_parse; gn_atem_modem_result(MR_OK); return; } gn_atem_modem_result(MR_ERROR);}/* Parser for entering message content (+CMGS) */void gn_atem_sms_parseText(char *buff){ static int index = 0; int i, length; char buffer[MAX_LINE_LENGTH]; gn_error error; length = strlen(buff); sms.user_data[0].type = GN_SMS_DATA_Text; for (i = 0; i < length; i++) { if (buff[i] == ModemRegisters[REG_CTRLZ]) { /* Exit SMS text mode with sending */ sms.user_data[0].u.text[index] = 0; sms.user_data[0].length = index; index = 0; Parser = gn_atem_at_parse; dprintf("Sending SMS to %s (text: %s)\n", data.sms->remote.number, data.sms->user_data[0].u.text); /* FIXME: set more SMS fields before sending */ error = gn_sms_send(&data, sm); if (error == GN_ERR_NONE) { gsprintf(buffer, MAX_LINE_LENGTH, "\n\r+CMGS: %d", data.sms->number); gn_atem_string_out(buffer); gn_atem_modem_result(MR_OK); } else { gn_atem_modem_result(MR_ERROR); } return; } else if (buff[i] == ModemRegisters[REG_ESCAPE]) { /* Exit SMS text mode without sending */ sms.user_data[0].u.text[index] = 0; sms.user_data[0].length = index; index = 0; Parser = gn_atem_at_parse; gn_atem_modem_result(MR_OK); return; } else { /* Appent next char to message text */ sms.user_data[0].u.text[index++] = buff[i]; } } /* reached the end of line so insert \n and wait for more */ sms.user_data[0].u.text[index++] = '\n'; gn_atem_string_out("\n\r> ");}/* Handle AT+C commands, this is a quick hack together at this stage. */bool gn_atem_command_plusc(char **buf){ float rflevel = -1; gn_rf_unit rfunits = GN_RF_CSQ; char buffer[MAX_LINE_LENGTH], buffer2[MAX_LINE_LENGTH]; int status, index; gn_error error; if (strncasecmp(*buf, "SQ", 2) == 0) { buf[0] += 2; data.rf_unit = &rfunits; data.rf_level = &rflevel; if (gn_sm_functions(GN_OP_GetRFLevel, &data, sm) == GN_ERR_NONE) { gsprintf(buffer, MAX_LINE_LENGTH, "\n\r+CSQ: %0.0f, 99", *(data.rf_level)); gn_atem_string_out(buffer); return (false); } else { return (true); } } /* AT+CGMI is Manufacturer information for the ME (phone) so it should be Nokia rather than gnokii... */ if (strncasecmp(*buf, "GMI", 3) == 0) { buf[0] += 3; gn_atem_string_out(_("\n\rNokia Mobile Phones")); return (false); } /* AT+CGSN is IMEI */ if (strncasecmp(*buf, "GSN", 3) == 0) { buf[0] += 3; strcpy(data.imei, "+CME ERROR: 0"); if (gn_sm_functions(GN_OP_GetImei, &data, sm) == GN_ERR_NONE) { gsprintf(buffer, MAX_LINE_LENGTH, "\n\r%s", data.imei); gn_atem_string_out(buffer); return (false); } else { return (true); } } /* AT+CGMR is Revision (hardware) */ if (strncasecmp(*buf, "GMR", 3) == 0) { buf[0] += 3; strcpy(data.revision, "+CME ERROR: 0"); if (gn_sm_functions(GN_OP_GetRevision, &data, sm) == GN_ERR_NONE) { gsprintf(buffer, MAX_LINE_LENGTH, "\n\r%s", data.revision); gn_atem_string_out(buffer); return (false); } else { return (true); } } /* AT+CGMM is Model code */ if (strncasecmp(*buf, "GMM", 3) == 0) { buf[0] += 3; strcpy(data.model, "+CME ERROR: 0"); if (gn_sm_functions(GN_OP_GetModel, &data, sm) == GN_ERR_NONE) { gsprintf(buffer, MAX_LINE_LENGTH, "\n\r%s", data.model); gn_atem_string_out(buffer); return (false); } else { return (true); } } /* AT+CMGD is deleting a message */ if (strncasecmp(*buf, "MGD", 3) == 0) { buf[0] += 3; switch (**buf) { case '=': buf[0]++; index = atoi(*buf); buf[0] += strlen(*buf); data.sms->memory_type = SMSType; data.sms->number = index; error = gn_sm_functions(GN_OP_DeleteSMS, &data, sm); switch (error) { case GN_ERR_NONE: break; default: gsprintf(buffer, MAX_LINE_LENGTH, "\n\r+CMS ERROR: %d\n\r", error); gn_atem_string_out(buffer); return (true); } break; default: return (true); } return (false); } /* AT+CMGF is mode selection for message format */ if (strncasecmp(*buf, "MGF", 3) == 0) { buf[0] += 3; switch (**buf) { case '=': buf[0]++; switch (**buf) { case '0': buf[0]++; MessageFormat = PDU_MODE; break; case '1': buf[0]++; MessageFormat = TEXT_MODE; break; default: return (true); } break; case '?': buf[0]++; gsprintf(buffer, MAX_LINE_LENGTH, "\n\r+CMGF: %d", MessageFormat); gn_atem_string_out(buffer); break; default: return (true); } return (false); } /* AT+CMGR is reading a message */ if (strncasecmp(*buf, "MGR", 3) == 0) { buf[0] += 3; switch (**buf) { case '=': buf[0]++; index = atoi(*buf); buf[0] += strlen(*buf); data.sms->memory_type = SMSType; data.sms->number = index; error = gn_sms_get(&data, sm); switch (error) { case GN_ERR_NONE: gn_atem_sms_print(buffer2, data.sms, MessageFormat); gsprintf(buffer, MAX_LINE_LENGTH, "\n\r+CMGR: %s", buffer2); gn_atem_string_out(buffer); break; default: gsprintf(buffer, MAX_LINE_LENGTH, "\n\r+CMS ERROR: %d\n\r", error); gn_atem_string_out(buffer); return (true); } break; default: return (true); } return (false); } /* AT+CMGS is sending a message */ if (strncasecmp(*buf, "MGS", 3) == 0) { buf[0] += 3; switch (**buf) { case '=': buf[0]++; if (sscanf(*buf, "\"%[+0-9a-zA-Z ]\"", sms.remote.number)) { Parser = gn_atem_sms_parseText; buf[0] += strlen(*buf); gn_atem_string_out("\n\r> "); } return (true); default: return (true); } return (false); } /* AT+CMGL is listing messages */ if (strncasecmp(*buf, "MGL", 3) == 0) { buf[0] += 3; status = -1; switch (**buf) { case 0: case '=': buf[0]++; /* process <stat> parameter */ if (*(*buf-1) == 0 || /* i.e. no parameter given */ strcasecmp(*buf, "1") == 0 || strcasecmp(*buf, "3") == 0 || strcasecmp(*buf, "\"REC READ\"") == 0 || strcasecmp(*buf, "\"STO SENT\"") == 0) { status = GN_SMS_Sent; } else if (strcasecmp(*buf, "0") == 0 || strcasecmp(*buf, "2") == 0 || strcasecmp(*buf, "\"REC UNREAD\"") == 0 || strcasecmp(*buf, "\"STO UNSENT\"") == 0) { status = GN_SMS_Unsent; } else if (strcasecmp(*buf, "4") == 0 || strcasecmp(*buf, "\"ALL\"") == 0) { status = 4; /* ALL */ } else { return true; } buf[0] += strlen(*buf); /* check all message storages */ for (index = 1; index <= 20; index++) { data.sms->memory_type = SMSType; data.sms->number = index; error = gn_sms_get(&data, sm); switch (error) { case GN_ERR_NONE: /* print messsage if it has the required status */ if (data.sms->status == status || status == 4 /* ALL */) { gn_atem_sms_print(buffer2, data.sms, MessageFormat); gsprintf(buffer, MAX_LINE_LENGTH, "\n\r+CMGL: %d,%s", index, buffer2); gn_atem_string_out(buffer); } break; case GN_ERR_EMPTYLOCATION: /* don't care if this storage is empty */ break; default: /* print other error codes and quit */ gsprintf(buffer, MAX_LINE_LENGTH, "\n\r+CMS ERROR: %d\n\r", error); gn_atem_string_out(buffer); return (true); } } break; default: return (true); } return (false); } return (true);}/* AT+G commands. Some of these responses are a bit tongue in cheek... */bool gn_atem_command_plusg(char **buf){ char buffer[MAX_LINE_LENGTH]; /* AT+GMI is Manufacturer information for the TA (Terminal Adaptor) */ if (strncasecmp(*buf, "MI", 3) == 0) { buf[0] += 2; gn_atem_string_out(_("\n\rHugh Blemings, Pavel Janik ml. and others...")); return (false); } /* AT+GMR is Revision information for the TA (Terminal Adaptor) */ if (strncasecmp(*buf, "MR", 3) == 0) { buf[0] += 2; gsprintf(buffer, MAX_LINE_LENGTH, "\n\r%s %s %s", VERSION, __TIME__, __DATE__); gn_atem_string_out(buffer); return (false); } /* AT+GMM is Model information for the TA (Terminal Adaptor) */ if (strncasecmp(*buf, "MM", 3) == 0) { buf[0] += 2; gsprintf(buffer, MAX_LINE_LENGTH, _("\n\rgnokii configured on %s for models %s"), sm->config.port_device, sm->driver.phone.models); gn_atem_string_out(buffer); return (false); } /* AT+GSN is Serial number for the TA (Terminal Adaptor) */ if (strncasecmp(*buf, "SN", 3) == 0) { buf[0] += 2; gsprintf(buffer, MAX_LINE_LENGTH, _("\n\rnone built in, choose your own")); gn_atem_string_out(buffer); return (false); } return (true);}/* Send a result string back. There is much work to do here, see the code in the isdn driver for an idea of where it's heading... */void gn_atem_modem_result(int code){ char buffer[16]; if (!(ModemRegisters[REG_VERBOSE] & BIT_VERBOSE)) { sprintf(buffer, "%d\n\r", code); gn_atem_string_out(buffer); } else { switch (code) { case MR_OK: gn_atem_string_out("OK\n\r"); break; case MR_ERROR: gn_atem_string_out("ERROR\n\r"); break; case MR_CARRIER: gn_atem_string_out("CARRIER\n\r"); break; case MR_CONNECT: gn_atem_string_out("CONNECT\n\r"); break; case MR_NOCARRIER: gn_atem_string_out("NO CARRIER\n\r"); break; case MR_RING: gn_atem_string_out("RING\n\r"); break; default: gn_atem_string_out(_("\n\rUnknown Result Code!\n\r")); break; } }}/* Get integer from char-pointer, set pointer to end of number stolen basically verbatim from ISDN code. */int gn_atem_num_get(char **p){ int v = -1; while (*p[0] >= '0' && *p[0] <= '9') { v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p[0]++) - '0'); } return v;}/* Write string to virtual modem port, either pty or STDOUT as appropriate. This function is only used during command mode - data pump is used when connected. */void gn_atem_string_out(char *buffer){ int count = 0; char out_char; while (count < strlen(buffer)) { /* Translate CR/LF/BS as appropriate */ switch (buffer[count]) { case '\r': out_char = ModemRegisters[REG_CR]; break; case '\n': out_char = ModemRegisters[REG_LF]; break; case '\b': out_char = ModemRegisters[REG_BS]; break; default: out_char = buffer[count]; break; } write(PtyWRFD, &out_char, 1); count++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -