📄 atgen.c
字号:
return ret;}/* AT_SetCharset * * before we start sending or receiving phonebook entries from the phone, * we should set a charset. this is done once before the first read or write. * * we try to chose a charset with hexadecimal representation. first ucs2 * (which is a hexencoded unicode charset) is tested and set if available. * if this fails for any reason, it is checked if the original charset is * GSM. if this is true, we try to set HEX (a hexencoded GSM charset). if * this again fails or is impossible, we try to use the GSM charset. if * the original charset was GSM nothing is done (we rely on not changing * anything by the failing tries before). if the original charset was * something else, we set the GSM charset. if this too fails, the user is * on his own, characters will be copied from or to the phone without * conversion. * * the whole bunch is needed to get a reasonable support for different * phones. eg a siemens s25 has GSM as original charset and aditional * supports only UCS2, a nokia 7110 has PCCP437 as original charset which * renders HEX unusable for us (in this case HEX will give a hexadecimal * encoding of the PCCP437 charset) and no UCS2. a ericsson t39 uses * GSM as original charset but has never heard of any hex encoded charset. * but this doesn't matter with IRDA and i haven't found a serial cable * in a shop yet, so this is no problem * * see AT_GetCharset, StoreDefaultCharset */static gn_error AT_SetCharset(gn_data *data, struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); gn_data tmpdata; gn_error error; if (drvinst->charset != AT_CHAR_UNKNOWN) return GN_ERR_NONE; /* check available charsets */ error = sm_message_send(10, GN_OP_AT_GetCharset, "AT+CSCS=?\r", state); if (error) return error; gn_data_clear(&tmpdata); error = sm_block_no_retry(GN_OP_AT_GetCharset, &tmpdata, state); if (!error && (drvinst->availcharsets & AT_CHAR_UCS2)) { /* UCS2 charset found. try to set it */ error = sm_message_send(15, GN_OP_Init, "AT+CSCS=\"UCS2\"\r", state); if (error) return error; error = sm_block_no_retry(GN_OP_Init, &tmpdata, state); if (!error) drvinst->charset = AT_CHAR_UCS2; } if (drvinst->charset != AT_CHAR_UNKNOWN) return GN_ERR_NONE; /* no UCS2 charset found or error occured */ if (drvinst->availcharsets & (AT_CHAR_GSM | AT_CHAR_HEXGSM)) { /* try to set HEX charset */ error = sm_message_send(14, GN_OP_Init, "AT+CSCS=\"HEX\"\r", state); if (error) return error; error = sm_block_no_retry(GN_OP_Init, &tmpdata, state); if (error) { /* no support for HEXGSM, be happy with GSM */ drvinst->charset = AT_CHAR_GSM; error = GN_ERR_NONE; } else drvinst->charset = AT_CHAR_HEXGSM; } else { drvinst->charset = drvinst->defaultcharset; error = (drvinst->charset == AT_CHAR_UNKNOWN) ? GN_ERR_FAILED : GN_ERR_NONE; } return error;}/* AT_GetCharset * * this function detects the current charset used by the phone. if it is * called immediatedly after a reset of the phone, this is also the * original charset of the phone. */static gn_error AT_GetCharset(gn_data *data, struct gn_statemachine *state){ gn_error ret; ret = sm_message_send(9, GN_OP_AT_GetCharset, "AT+CSCS?\r", state); if (ret) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_AT_GetCharset, data, state);}static gn_error AT_Identify(gn_data *data, struct gn_statemachine *state){ gn_error ret; if ((ret = state->driver.functions(GN_OP_GetModel, data, state))) return ret; if ((ret = state->driver.functions(GN_OP_GetManufacturer, data, state))) return ret; if ((ret = state->driver.functions(GN_OP_GetRevision, data, state))) return ret; return state->driver.functions(GN_OP_GetImei, data, state);}static gn_error AT_GetModel(gn_data *data, struct gn_statemachine *state){ if (sm_message_send(8, GN_OP_Identify, "AT+CGMM\r", state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_Identify, data, state);}static gn_error AT_GetManufacturer(gn_data *data, struct gn_statemachine *state){ if (sm_message_send(8, GN_OP_Identify, "AT+CGMI\r", state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_Identify, data, state);}static gn_error AT_GetRevision(gn_data *data, struct gn_statemachine *state){ if (sm_message_send(8, GN_OP_Identify, "AT+CGMR\r", state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_Identify, data, state);}static gn_error AT_GetIMEI(gn_data *data, struct gn_statemachine *state){ if (sm_message_send(8, GN_OP_Identify, "AT+CGSN\r", state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_Identify, data, state);}/* gets battery level and power source */static gn_error AT_GetBattery(gn_data *data, struct gn_statemachine *state){ if (sm_message_send(7, GN_OP_GetBatteryLevel, "AT+CBC\r", state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_GetBatteryLevel, data, state);}static gn_error AT_GetRFLevel(gn_data *data, struct gn_statemachine *state){ if (sm_message_send(7, GN_OP_GetRFLevel, "AT+CSQ\r", state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_GetRFLevel, data, state);}static gn_error AT_GetMemoryStatus(gn_data *data, struct gn_statemachine *state){ gn_error ret; ret = at_memory_type_set(data->memory_status->memory_type, state); if (ret) return ret; if (sm_message_send(9, GN_OP_GetMemoryStatus, "AT+CPBS?\r", state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_GetMemoryStatus, data, state);}static gn_error AT_GetMemoryRange(gn_data *data, struct gn_statemachine *state){ gn_error ret; ret = sm_message_send(10, GN_OP_AT_GetMemoryRange, "AT+CPBR=?\r", state); if (ret) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_AT_GetMemoryRange, data, state);}static gn_error AT_ReadPhonebook(gn_data *data, struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); char req[32]; gn_error ret; ret = state->driver.functions(GN_OP_AT_SetCharset, data, state); if (ret) return ret; ret = at_memory_type_set(data->phonebook_entry->memory_type, state); if (ret) return ret; sprintf(req, "AT+CPBR=%d\r", data->phonebook_entry->location+drvinst->memoryoffset); if (sm_message_send(strlen(req), GN_OP_ReadPhonebook, req, state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_ReadPhonebook, data, state);}static gn_error AT_WritePhonebook(gn_data *data, struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); int len, ofs; char req[256], *tmp; gn_error ret; ret = at_memory_type_set(data->phonebook_entry->memory_type, state); if (ret) return ret; if (data->phonebook_entry->empty || (!(*(data->phonebook_entry->name)) && !(*(data->phonebook_entry->number)))) return AT_DeletePhonebook(data, state); else { ret = state->driver.functions(GN_OP_AT_SetCharset, data, state); if (ret) return ret; ofs = sprintf(req, "AT+CPBW=%d,\"%s\",%s,\"", data->phonebook_entry->location+drvinst->memoryoffset, data->phonebook_entry->number, data->phonebook_entry->number[0] == '+' ? "145" : "129"); len = strlen(data->phonebook_entry->name); tmp = req + ofs; len = at_encode(drvinst->charset, tmp, data->phonebook_entry->name, len); tmp[len++] = '"'; tmp[len++] = '\r'; len += ofs; } if (sm_message_send(len, GN_OP_WritePhonebook, req, state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_WritePhonebook, data, state);}static gn_error AT_DeletePhonebook(gn_data *data, struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); int len; char req[64]; gn_error ret; if (!data->phonebook_entry) return GN_ERR_INTERNALERROR; ret = at_memory_type_set(data->phonebook_entry->memory_type, state); if (ret) return ret; len = sprintf(req, "AT+CPBW=%d\r", data->phonebook_entry->location+drvinst->memoryoffset); if (sm_message_send(len, GN_OP_DeletePhonebook, req, state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_DeletePhonebook, data, state);}static gn_error AT_CallDivert(gn_data *data, struct gn_statemachine *state){ char req[64]; if (!data->call_divert) return GN_ERR_UNKNOWN; sprintf(req, "AT+CCFC="); switch (data->call_divert->type) { case GN_CDV_AllTypes: strcat(req, "4"); break; case GN_CDV_Busy: strcat(req, "1"); break; case GN_CDV_NoAnswer: strcat(req, "2"); break; case GN_CDV_OutOfReach: strcat(req, "3"); break; default: dprintf("3. %d\n", data->call_divert->type); return GN_ERR_NOTIMPLEMENTED; } if (data->call_divert->operation == GN_CDV_Register) sprintf(req, "%s,%d,\"%s\",%d,,,%d", req, data->call_divert->operation, data->call_divert->number.number, data->call_divert->number.type, data->call_divert->timeout); else sprintf(req, "%s,%d", req, data->call_divert->operation); strcat(req, "\r"); dprintf("%s", req); if (sm_message_send(strlen(req), GN_OP_CallDivert, req, state)) return GN_ERR_NOTREADY; return sm_wait_for(GN_OP_CallDivert, data, state);}static gn_error AT_SetPDUMode(gn_data *data, struct gn_statemachine *state){ if (sm_message_send(10, GN_OP_AT_SetPDUMode, "AT+CMGF=0\r", state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_AT_SetPDUMode, data, state);}static gn_error AT_GetSMSStatus(gn_data *data, struct gn_statemachine *state){ gn_error ret; if (!data->sms_status) return GN_ERR_INTERNALERROR; ret = sm_message_send(13, GN_OP_GetSMSStatus, "AT+CPMS=\"SM\"\r", state); if (ret != GN_ERR_NONE) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_GetSMSStatus, data, state);}static gn_error AT_SendSMS(gn_data *data, struct gn_statemachine *state){ return AT_WriteSMS(data, state, "CMGS");}static gn_error AT_SaveSMS(gn_data *data, struct gn_statemachine *state){ gn_error ret = AT_SetSMSMemoryType(data->raw_sms->memory_type, state); if (ret) return ret; return AT_WriteSMS(data, state, "CMGW");}static gn_error AT_WriteSMS(gn_data *data, struct gn_statemachine *state, unsigned char *cmd){ unsigned char req[10240], req2[5120]; gn_error error; unsigned int length, tmp, offset = 0; if (!data->raw_sms) return GN_ERR_INTERNALERROR; /* Select PDU mode */ error = state->driver.functions(GN_OP_AT_SetPDUMode, data, state); if (error) { dprintf("PDU mode not supported\n"); return error; } dprintf("PDU mode set\n"); /* Prepare the message and count the size */ memcpy(req2, data->raw_sms->message_center, data->raw_sms->message_center[0] + 1); offset += data->raw_sms->message_center[0]; /* Validity period in relative format */ req2[offset + 1] = 0x01 | 0x10; if (data->raw_sms->reject_duplicates) req2[offset + 1] |= 0x04; if (data->raw_sms->report) req2[offset + 1] |= 0x20; if (data->raw_sms->udh_indicator) req2[offset + 1] |= 0x40; if (data->raw_sms->reply_via_same_smsc) req2[offset + 1] |= 0x80; req2[offset + 2] = 0x00; /* Message Reference */ tmp = data->raw_sms->remote_number[0]; if (tmp % 2) tmp++; tmp /= 2; memcpy(req2 + offset + 3, data->raw_sms->remote_number, tmp + 2); offset += tmp + 1; req2[offset + 4] = data->raw_sms->pid; req2[offset + 5] = data->raw_sms->dcs; req2[offset + 6] = 0xaa; /* Validity period */ req2[offset + 7] = data->raw_sms->length; memcpy(req2 + offset + 8, data->raw_sms->user_data, data->raw_sms->user_data_length); length = data->raw_sms->user_data_length + offset + 8; /* Length in AT mode is the length of the full message minus * SMSC field length */ sprintf(req, "AT+%s=%d\r", cmd, length - data->raw_sms->message_center[0] - 1); dprintf("Sending initial sequence\n"); if (sm_message_send(strlen(req), GN_OP_AT_Prompt, req, state)) return GN_ERR_NOTREADY; error = sm_block_no_retry(GN_OP_AT_Prompt, data, state); dprintf("Got response %d\n", error); if (error) return error; bin2hex(req, req2, length); req[length * 2] = 0x1a; req[length * 2 + 1] = 0; dprintf("Sending frame: %s\n", req); if (sm_message_send(strlen(req), GN_OP_SendSMS, req, state)) return GN_ERR_NOTREADY; do { error = sm_block_no_retry_timeout(GN_OP_SendSMS, state->config.smsc_timeout, data, state); } while (!state->config.smsc_timeout && error == GN_ERR_TIMEOUT); return error;}static gn_error AT_GetSMS(gn_data *data, struct gn_statemachine *state){ unsigned char req[16]; gn_error err = AT_SetSMSMemoryType(data->raw_sms->memory_type, state); if (err) return err; sprintf(req, "AT+CMGR=%d\r", data->raw_sms->number); dprintf("%s", req); if (sm_message_send(strlen(req), GN_OP_GetSMS, req, state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_GetSMS, data, state);}static gn_error AT_DeleteSMS(gn_data *data, struct gn_statemachine *state){ unsigned char req[16]; gn_error err = AT_SetSMSMemoryType(data->raw_sms->memory_type, state); if (err) return err; sprintf(req, "AT+CMGD=%d\r", data->sms->number); dprintf("%s", req);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -