📄 atgen.c
字号:
if (!data->raw_sms) return GN_ERR_INTERNALERROR; tmp = strrchr(buf.line2, ','); sms_len = atoi(tmp+1); if (sms_len == 0) return GN_ERR_EMPTYLOCATION; sms_len = strlen(buf.line3) / 2; tmp = calloc(sms_len, 1); if (!tmp) { dprintf("Not enough memory for buffer.\n"); return GN_ERR_INTERNALERROR; } dprintf("%s\n", buf.line3); hex2bin(tmp, buf.line3, sms_len); l = tmp[offset] + 1; if (l > sms_len || l > GN_SMS_SMSC_NUMBER_MAX_LENGTH) { dprintf("Invalid message center length (%d)\n", l); ret = GN_ERR_INTERNALERROR; goto out; } memcpy(data->raw_sms->message_center, tmp, l); offset += l; data->raw_sms->type = (tmp[offset] & 0x03) << 1; data->raw_sms->udh_indicator = tmp[offset]; data->raw_sms->more_messages = tmp[offset]; data->raw_sms->report_status = tmp[offset]; l = (tmp[offset + 1] % 2) ? tmp[offset + 1] + 1 : tmp[offset + 1] ; l = l / 2 + 2; if (l + offset + 11 > sms_len || l > GN_SMS_NUMBER_MAX_LENGTH) { dprintf("Invalid remote number length (%d)\n", l); ret = GN_ERR_INTERNALERROR; goto out; } memcpy(data->raw_sms->remote_number, tmp + offset + 1, l); offset += l; data->raw_sms->reply_via_same_smsc = 0; data->raw_sms->reject_duplicates = 0; data->raw_sms->report = 0; data->raw_sms->reference = 0; data->raw_sms->pid = tmp[offset + 1]; data->raw_sms->dcs = tmp[offset + 2]; memcpy(data->raw_sms->smsc_time, tmp + offset + 3, 7); data->raw_sms->length = tmp[offset + 10] & 0x00ff; if (sms_len - offset - 11 > 1000) { dprintf("Phone gave as poisonous (too short?) reply %s, either phone went crazy or communication went out of sync\n", buf.line3); ret = GN_ERR_INTERNALERROR; goto out; } memcpy(data->raw_sms->user_data, tmp + offset + 11, sms_len - offset - 11);out: free(tmp); return ret;}/* ReplyGetCharset * * parses the reponse from a check for the actual charset or the * available charsets. a bracket in the response is taken as a request * for available charsets. */static gn_error ReplyGetCharset(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); at_line_buffer buf; int i; if (buffer[0] != GN_AT_OK) return GN_ERR_UNKNOWN; buf.line1 = buffer + 1; buf.length= length; splitlines(&buf); if (!strncmp(buf.line1, "AT+CSCS?", 8)) { /* return current charset */ drvinst->charset = AT_CHAR_UNKNOWN; i = 0; while (atcharsets[i].str && drvinst->charset != AT_CHAR_UNKNOWN) { if (strstr(buf.line2, atcharsets[i].str)) drvinst->charset = atcharsets[i].charset; i++; } return GN_ERR_NONE; } else if (!strncmp(buf.line1, "AT+CSCS=", 8)) { /* return available charsets */ drvinst->availcharsets = 0; i = 0; while (atcharsets[i].str) { if (strstr(buf.line2, atcharsets[i].str)) drvinst->availcharsets |= atcharsets[i].charset; i++; } return GN_ERR_NONE; } return GN_ERR_FAILED;}static gn_error ReplyGetSecurityCodeStatus(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state){ at_line_buffer buf; char *pos; if (buffer[0] != GN_AT_OK) return GN_ERR_UNKNOWN; buf.line1 = buffer + 1; buf.length= length; splitlines(&buf); if (data->security_code && !strncmp(buf.line1, "AT+CPIN", 7)) { if (strncmp(buf.line2, "+CPIN: ", 7)) { data->security_code->type = 0; return GN_ERR_INTERNALERROR; } pos = 7 + buf.line2; if (!strncmp(pos, "READY", 5)) { data->security_code->type = GN_SCT_None; return GN_ERR_NONE; } if (!strncmp(pos, "SIM ", 4)) { pos += 4; if (!strncmp(pos, "PIN2", 4)) { data->security_code->type = GN_SCT_Pin2; } if (!strncmp(pos, "PUK2", 4)) { data->security_code->type = GN_SCT_Puk2; } if (!strncmp(pos, "PIN", 3)) { data->security_code->type = GN_SCT_Pin; } if (!strncmp(pos, "PUK", 3)) { data->security_code->type = GN_SCT_Puk; } } } return GN_ERR_NONE;}static gn_error ReplyGetNetworkInfo(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state){ at_driver_instance *drvinst = AT_DRVINST(state); at_line_buffer buf; char *pos; char **strings; if (!data->network_info) return GN_ERR_INTERNALERROR; if (buffer[0] != GN_AT_OK) return GN_ERR_UNKNOWN; buf.line1 = buffer + 1; buf.length= length; splitlines(&buf); if (!strncmp(buf.line1, "AT+CREG?", 8)) { char tmp[3] = {0, 0, 0}; strings = gnokii_strsplit(buf.line2, ",", 4); if (strings[2] && strlen(strings[2]) >= 6) { pos = strings[2]; pos++; tmp[0] = pos[0]; tmp[1] = pos[1]; data->network_info->LAC[0] = strtol(tmp, NULL, 16); tmp[0] = pos[2]; tmp[1] = pos[3]; data->network_info->LAC[1] = strtol(tmp, NULL, 16); } if (strings[3] && strlen(strings[3]) >= 6) { pos = strings[3]; pos++; tmp[0] = pos[0]; tmp[1] = pos[1]; data->network_info->cell_id[0] = strtol(tmp, NULL, 16); tmp[0] = pos[2]; tmp[1] = pos[3]; data->network_info->cell_id[1] = strtol(tmp, NULL, 16); } gnokii_strfreev(strings); } else if (!strncmp(buf.line1, "AT+COPS?", 8)) { char tmp[128]; int format, l; memset(tmp, 0, sizeof(tmp)); strings = gnokii_strsplit(buf.line2, ",", 3); format = atoi(strings[1]); switch (format) { case 0: /* network operator name given */ pos = strings[2]; pos++; pos = strtok(pos, "\""); at_decode(drvinst->charset, tmp, pos, strlen(pos)); snprintf(data->network_info->network_code, sizeof(data->network_info->network_code), gn_network_code_get(tmp)); break; case 2: /* network operator code given */ if (strlen(strings[2]) >= 6) { data->network_info->network_code[0] = strings[2][1]; data->network_info->network_code[1] = strings[2][2]; data->network_info->network_code[2] = strings[2][3]; data->network_info->network_code[3] = ' '; data->network_info->network_code[4] = strings[2][4]; data->network_info->network_code[5] = strings[2][5]; data->network_info->network_code[6] = 0; } else { /* probably incorrect */ snprintf(data->network_info->network_code, sizeof(data->network_info->network_code), strings[2]); } break; default: /* FIXME: add error handling */ break; } gnokii_strfreev(strings); } return GN_ERR_NONE;}/* General reply function for phone responses. buffer[0] holds the compiled * success of the result (OK, ERROR, ... ). see links/atbus.h and links/atbus.c * for reference */static gn_error Reply(int messagetype, unsigned char *buffer, int length, gn_data *data, struct gn_statemachine *state){ return (buffer[0] != GN_AT_OK) ? GN_ERR_UNKNOWN : GN_ERR_NONE;}static gn_error Initialise(gn_data *setupdata, struct gn_statemachine *state){ at_driver_instance *drvinst; gn_data data; gn_error ret = GN_ERR_NONE; char model[20]; char manufacturer[20]; int i; dprintf("Initializing AT capable mobile phone ...\n"); /* Copy in the phone info */ memcpy(&(state->driver), &driver_at, sizeof(gn_driver)); if (!(drvinst = malloc(sizeof(at_driver_instance)))) return GN_ERR_MEMORYFULL; state->driver.incoming_functions = drvinst->incoming_functions; AT_DRVINST(state) = drvinst; drvinst->memorytype = GN_MT_XX; drvinst->memoryoffset = 0; drvinst->memorysize = 100; drvinst->smsmemorytype = GN_MT_XX; drvinst->defaultcharset = AT_CHAR_UNKNOWN; drvinst->charset = AT_CHAR_UNKNOWN; drvinst->if_pos = 0; for (i = 0; i < GN_OP_AT_Max; i++) { drvinst->functions[i] = NULL; drvinst->incoming_functions[i].message_type = 0; drvinst->incoming_functions[i].functions = NULL; } for (i = 0; i < ARRAY_LEN(at_function_init); i++) { at_insert_send_function(at_function_init[i].gop, at_function_init[i].sfunc, state); at_insert_recv_function(at_function_init[i].gop, at_function_init[i].rfunc, state); } switch (state->config.connection_type) { case GN_CT_Serial: case GN_CT_Bluetooth: case GN_CT_Irda: case GN_CT_TCP: if (!strcmp(setupdata->model, "AT-HW")) ret = atbus_initialise(true, state); else ret = atbus_initialise(false, state); break; default: ret = GN_ERR_NOTSUPPORTED; break; } if (ret) goto out; sm_initialise(state); SoftReset(&data, state); SetEcho(&data, state); /* * detect manufacturer and model for further initialization */ gn_data_clear(&data); data.model = model; ret = state->driver.functions(GN_OP_GetModel, &data, state); if (ret) goto out; data.manufacturer = manufacturer; ret = state->driver.functions(GN_OP_GetManufacturer, &data, state); if (ret) goto out; if (!strncasecmp(manufacturer, "bosch", 5)) at_bosch_init(model, setupdata->model, state); else if (!strncasecmp(manufacturer, "ericsson", 8)) at_ericsson_init(model, setupdata->model, state); else if (!strncasecmp(manufacturer, "nokia", 5)) at_nokia_init(model, setupdata->model, state); else if (!strncasecmp(manufacturer, "siemens", 7)) at_siemens_init(model, setupdata->model, state); StoreDefaultCharset(state); dprintf("Initialisation completed\n");out: if (ret) { dprintf("Initialization failed (%d)\n", ret); free(AT_DRVINST(state)); AT_DRVINST(state) = NULL; } return ret;}static gn_error Terminate(gn_data *data, struct gn_statemachine *state){ if (AT_DRVINST(state)) { free(AT_DRVINST(state)); AT_DRVINST(state) = NULL; } return pgen_terminate(data, state);}void splitlines(at_line_buffer *buf){ char *pos; pos = findcrlf(buf->line1, 0, buf->length); if (pos) { *pos = 0; buf->line2 = skipcrlf(++pos); } else { buf->line2 = buf->line1; } pos = findcrlf(buf->line2, 1, buf->length); if (pos) { *pos = 0; buf->line3 = skipcrlf(++pos); } else { buf->line3 = buf->line2; } pos = findcrlf(buf->line3, 1, buf->length); if (pos) { *pos = 0; buf->line4 = skipcrlf(++pos); } else { buf->line4 = buf->line3; }}/* * increments the argument until a char unequal to * <cr> or <lf> is found. returns the new position. */char *skipcrlf(unsigned char *str){ if (str == NULL) return str; while ((*str == '\n') || (*str == '\r') || (*str > 127)) str++; return str;}/* * searches for <cr> or <lf> and returns the first * occurrence. if test is set, the gsm char @ which * is 0x00 is not considered as end of string. * return NULL if no <cr> or <lf> was found in the * range of max bytes. */char *findcrlf(unsigned char *str, int test, int max){ if (str == NULL) return str; while ((*str != '\n') && (*str != '\r') && ((*str != '\0') || test) && (max > 0)) { str++; max--; } if ((*str == '\0') || ((max == 0) && (*str != '\n') && (*str != '\r'))) return NULL; return str;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -