📄 atgen.c
字号:
/* $Id: atgen.c,v 1.101 2004/04/11 14:15:13 pkot Exp $ G N O K I I A Linux/Unix toolset and driver for mobile phones. This file is part of gnokii. Gnokii is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Gnokii is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gnokii; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Copyright (C) 2001 Manfred Jonsson <manfred.jonsson@gmx.de> Copyright (C) 2002 Pawel Kot <pkot@linuxnews.pl> This file provides functions specific to generic AT command compatible phones. See README for more details on supported mobile phones.*/#include <string.h>#include <stdlib.h>#include <ctype.h>#include "gnokii-internal.h"#include "gnokii.h"#include "phones/generic.h"#include "phones/atgen.h"#include "phones/atbosch.h"#include "phones/ateric.h"#include "phones/atnok.h"#include "phones/atsie.h"#include "links/atbus.h"static gn_error Initialise(gn_data *setupdata, struct gn_statemachine *state);static gn_error Terminate(gn_data *data, struct gn_statemachine *state);static gn_error Functions(gn_operation op, gn_data *data, struct gn_statemachine *state);static gn_error Reply(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyIdentify(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyGetRFLevel(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyGetBattery(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyReadPhonebook(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyMemoryStatus(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyMemoryRange(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyCallDivert(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyGetPrompt(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyGetSMSStatus(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplySendSMS(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyGetSMS(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);/* static gn_error ReplyDeleteSMS(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state); */static gn_error ReplyGetCharset(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyGetSMSCenter(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyGetSecurityCodeStatus(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error ReplyGetNetworkInfo(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state);static gn_error AT_Identify(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetModel(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetRevision(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetIMEI(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetManufacturer(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetBattery(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetRFLevel(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetMemoryStatus(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetMemoryRange(gn_data *data, struct gn_statemachine *state);static gn_error AT_ReadPhonebook(gn_data *data, struct gn_statemachine *state);static gn_error AT_WritePhonebook(gn_data *data, struct gn_statemachine *state);static gn_error AT_DeletePhonebook(gn_data *data, struct gn_statemachine *state);static gn_error AT_CallDivert(gn_data *data, struct gn_statemachine *state);static gn_error AT_SetPDUMode(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetSMSStatus(gn_data *data, struct gn_statemachine *state);static gn_error AT_SendSMS(gn_data *data, struct gn_statemachine *state);static gn_error AT_SaveSMS(gn_data *data, struct gn_statemachine *state);static gn_error AT_WriteSMS(gn_data *data, struct gn_statemachine *state, unsigned char *cmd);static gn_error AT_GetSMS(gn_data *data, struct gn_statemachine *state);static gn_error AT_DeleteSMS(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetCharset(gn_data *data, struct gn_statemachine *state);static gn_error AT_SetCharset(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetSMSCenter(gn_data *data, struct gn_statemachine *state);static gn_error AT_EnterSecurityCode(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetSecurityCodeStatus(gn_data *data, struct gn_statemachine *state);static gn_error AT_DialVoice(gn_data *data, struct gn_statemachine *state);static gn_error AT_GetNetworkInfo(gn_data *data, struct gn_statemachine *state);static gn_error AT_AnswerCall(gn_data *data, struct gn_statemachine *state);static gn_error AT_CancelCall(gn_data *data, struct gn_statemachine *state);typedef struct { int gop; at_send_function_type sfunc; at_recv_function_type rfunc;} at_function_init_type;/* Mobile phone information */static at_function_init_type at_function_init[] = { { GN_OP_Init, NULL, Reply }, { GN_OP_Terminate, Terminate, Reply }, { GN_OP_GetModel, AT_GetModel, ReplyIdentify }, { GN_OP_GetRevision, AT_GetRevision, ReplyIdentify }, { GN_OP_GetImei, AT_GetIMEI, ReplyIdentify }, { GN_OP_GetManufacturer, AT_GetManufacturer, ReplyIdentify }, { GN_OP_Identify, AT_Identify, ReplyIdentify }, { GN_OP_GetBatteryLevel, AT_GetBattery, ReplyGetBattery }, { GN_OP_GetPowersource, AT_GetBattery, ReplyGetBattery }, { GN_OP_GetRFLevel, AT_GetRFLevel, ReplyGetRFLevel }, { GN_OP_GetMemoryStatus, AT_GetMemoryStatus, ReplyMemoryStatus }, { GN_OP_AT_GetMemoryRange, AT_GetMemoryRange, ReplyMemoryRange }, { GN_OP_ReadPhonebook, AT_ReadPhonebook, ReplyReadPhonebook }, { GN_OP_WritePhonebook, AT_WritePhonebook, Reply }, { GN_OP_DeletePhonebook, AT_DeletePhonebook, Reply }, { GN_OP_CallDivert, AT_CallDivert, ReplyCallDivert }, { GN_OP_AT_SetPDUMode, AT_SetPDUMode, Reply }, { GN_OP_AT_Prompt, NULL, ReplyGetPrompt }, { GN_OP_GetSMSStatus, AT_GetSMSStatus, ReplyGetSMSStatus }, { GN_OP_SendSMS, AT_SendSMS, ReplySendSMS }, { GN_OP_SaveSMS, AT_SaveSMS, ReplySendSMS }, { GN_OP_GetSMS, AT_GetSMS, ReplyGetSMS }, { GN_OP_DeleteSMS, AT_DeleteSMS, Reply }, { GN_OP_AT_GetCharset, AT_GetCharset, ReplyGetCharset }, { GN_OP_AT_SetCharset, AT_SetCharset, Reply }, { GN_OP_GetSMSCenter, AT_GetSMSCenter, ReplyGetSMSCenter }, { GN_OP_GetSecurityCodeStatus, AT_GetSecurityCodeStatus, ReplyGetSecurityCodeStatus }, { GN_OP_EnterSecurityCode, AT_EnterSecurityCode, Reply }, { GN_OP_MakeCall, AT_DialVoice, Reply }, { GN_OP_AnswerCall, AT_AnswerCall, Reply }, { GN_OP_CancelCall, AT_CancelCall, Reply }, { GN_OP_GetNetworkInfo, AT_GetNetworkInfo, ReplyGetNetworkInfo },};static char *strip_quotes(char *s){ char *t; if (*s == '"') { if ((t = strrchr(++s, '"'))) { *t = '\0'; } } return s;}static char *strip_brackets(char *s){ char *t ; if (*s == '(') { if ((t = strrchr(++s, ')'))) { *t = '\0'; } } return s;}static void reply_simpletext(char *l1, char *l2, char *c, char *t){ if ((strncmp(l1, c, 5) == 0) && (t != NULL)) { if (strncmp(l2, c, 7) == 0) { strcpy(t, strip_quotes(l2+7)); } else { strcpy(t, l2); } }}gn_driver driver_at = { NULL, pgen_incoming_default, { "AT|AT-HW", /* Supported models */ 99, /* Max RF Level */ 0, /* Min RF Level */ GN_RF_CSQ, /* RF level units */ 100, /* Max Battery Level */ 0, /* Min Battery Level */ GN_BU_Percentage, /* Battery level units */ 0, /* Have date/time support */ 0, /* Alarm supports time only */ 0, /* Alarms available - FIXME */ 0, 0, /* Startup logo size - FIXME */ 0, 0, /* Op logo size */ 0, 0 /* Caller logo size */ }, Functions, NULL};static char *memorynames[] = { "ME", /* Internal memory of the mobile equipment */ "SM", /* SIM card memory */ "FD", /* Fixed dial numbers */ "ON", /* Own numbers */ "EN", /* Emergency numbers */ "DC", /* Dialled numbers */ "RC", /* Received numbers */ "MC", /* Missed numbers */ "LD", /* Last dialed */ "MT", /* combined ME and SIM phonebook */ "TA", /* for compatibility only: TA=computer memory */ "CB", /* Currently selected memory */};typedef struct { char *str; at_charset charset;} at_charset_map_t;static at_charset_map_t atcharsets[] = { { "GSM", AT_CHAR_GSM }, { "HEX", AT_CHAR_HEXGSM }, { "UCS2", AT_CHAR_UCS2 }, { NULL, AT_CHAR_UNKNOWN },};static gn_error Functions(gn_operation op, gn_data *data, struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); if (op == GN_OP_Init) return Initialise(data, state); if (drvinst && op == GN_OP_Terminate) return Terminate(data, state); if (!drvinst) return GN_ERR_INTERNALERROR; if ((op > GN_OP_Init) && (op < GN_OP_AT_Max)) if (drvinst->functions[op]) return (*(drvinst->functions[op]))(data, state); return GN_ERR_NOTIMPLEMENTED;}/* Functions to encode and decode strings */static int at_encode(int charset, char *dst, char *src, int len) { switch (charset) { case AT_CHAR_GSM: len = char_ascii_encode(dst, src, len); break; case AT_CHAR_HEXGSM: char_hex_encode(dst, src, len); len *= 2; break; case AT_CHAR_UCS2: char_ucs2_encode(dst, src, len); len *= 4; break; default: memcpy(dst, src, len); break; } dst[len] = '\0'; return len;}static void at_decode(int charset, char *dst, char *src, int len) { switch (charset) { case AT_CHAR_GSM: char_ascii_decode(dst, src, len); break; case AT_CHAR_HEXGSM: char_hex_decode(dst, src, len); len *= 2; break; case AT_CHAR_UCS2: char_ucs2_decode(dst, src, len); len *= 4; break; default: memcpy(dst, src, len); break; } dst[len] = '\0';}at_recv_function_type at_insert_recv_function(int type, at_recv_function_type func, struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); at_recv_function_type oldfunc; int i; if (type >= GN_OP_AT_Max) { return (at_recv_function_type) -1; } if (drvinst->if_pos == 0) { drvinst->incoming_functions[0].message_type = type; drvinst->incoming_functions[0].functions = func; drvinst->if_pos++; return NULL; } for (i = 0; i < drvinst->if_pos; i++) { if (drvinst->incoming_functions[i].message_type == type) { oldfunc = drvinst->incoming_functions[i].functions; drvinst->incoming_functions[i].functions = func; return oldfunc; } } if (drvinst->if_pos < GN_OP_AT_Max-1) { drvinst->incoming_functions[drvinst->if_pos].message_type = type; drvinst->incoming_functions[drvinst->if_pos].functions = func; drvinst->if_pos++; } return NULL;}at_send_function_type at_insert_send_function(int type, at_send_function_type func, struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); at_send_function_type f; f = drvinst->functions[type]; drvinst->functions[type] = func; return f;}static gn_error SoftReset(gn_data *data, struct gn_statemachine *state){ if (sm_message_send(4, GN_OP_Init, "ATZ\r", state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_Init, data, state);}static gn_error SetEcho(gn_data *data, struct gn_statemachine *state){ if (sm_message_send(5, GN_OP_Init, "ATE1\r", state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_Init, data, state);}/* StoreDefaultCharset * * for a correct communication with the phone for phonebook entries or * SMS text mode, we need to set a suited charset. a suited charset * doesn't contain characters which are also used by the serial line for * software handshake. so the GSM charset (or PC437, latin-1, etc) are * a bad choice. * so the GSM specification defines the HEX charset which is a hexidecimal * representation of the "original" charset. this is a good choice for the * above problem. but the GSM specification defines the default charset and * no "original" charset. * so what we do is to ask the phone (after a reset) for its original * charset and store the result for future referece. we don't do a full * initialization for speed reason. at further processing we can chose * a working charset if needed. * * see also AT_SetCharset, AT_GetCharset */static void StoreDefaultCharset(struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); gn_data data; gn_error error; gn_data_clear(&data); error = state->driver.functions(GN_OP_AT_GetCharset, &data, state); drvinst->defaultcharset = error ? AT_CHAR_UNKNOWN : drvinst->charset; drvinst->charset = AT_CHAR_UNKNOWN;}gn_error at_memory_type_set(gn_memory_type mt, struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); gn_data data; char req[32]; gn_error ret = GN_ERR_NONE; if (mt != drvinst->memorytype) { sprintf(req, "AT+CPBS=\"%s\"\r", memorynames[mt]); ret = sm_message_send(13, GN_OP_Init, req, state); if (ret) return GN_ERR_NOTREADY; gn_data_clear(&data); ret = sm_block_no_retry(GN_OP_Init, &data, state); if (ret == GN_ERR_NONE) drvinst->memorytype = mt; gn_data_clear(&data); ret = state->driver.functions(GN_OP_AT_GetMemoryRange, &data, state); } return ret;}gn_error AT_SetSMSMemoryType(gn_memory_type mt, struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); gn_data data; char req[32]; gn_error ret = GN_ERR_NONE; if (mt != drvinst->smsmemorytype) { sprintf(req, "AT+CPMS=\"%s\"\r", memorynames[mt]); ret = sm_message_send(13, GN_OP_Init, req, state); if (ret != GN_ERR_NONE) return GN_ERR_NOTREADY; gn_data_clear(&data); ret = sm_block_no_retry(GN_OP_Init, &data, state); if (ret == GN_ERR_NONE) drvinst->smsmemorytype = mt; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -