usock.c.svn-base
来自「Linux下gsm/gprs modem的看守程序。支持短信发送与接受。」· SVN-BASE 代码 · 共 1,745 行 · 第 1/4 页
SVN-BASE
1,745 行
reason = (int *) ((void *)gph + sizeof(*gph)); sprintf(buf, "%d,2", *reason); atcmd_len = 1 + strlen("AT+CCFC=") + strlen(buf); cmd = atcmd_fill("AT+CCFC=", atcmd_len, &voicecall_fwd_stat_cb, gu, gph->id, NULL); if (!cmd) return -ENOMEM; sprintf(cmd->buf, "AT+CCFC=%s", buf); break; case GSMD_VOICECALL_FWD_REG: if(len < sizeof(*gph) + sizeof(int)) return -EINVAL; gcfr = (struct gsmd_call_fwd_reg *) ((void *)gph + sizeof(*gph)); sprintf(buf, "%d,3,\"%s\"", gcfr->reason, gcfr->addr.number); atcmd_len = 1 + strlen("AT+CCFC=") + strlen(buf); cmd = atcmd_fill("AT+CCFC=", atcmd_len, &usock_cmd_cb, gu, gph->id, NULL); if (!cmd) return -ENOMEM; sprintf(cmd->buf, "AT+CCFC=%s", buf); break; case GSMD_VOICECALL_FWD_ERAS: if(len < sizeof(*gph) + sizeof(int)) return -EINVAL; reason = (int *) ((void *)gph + sizeof(*gph)); sprintf(buf, "%d,4", *reason); atcmd_len = 1 + strlen("AT+CCFC=") + strlen(buf); cmd = atcmd_fill("AT+CCFC=", atcmd_len, &usock_cmd_cb, gu, gph->id, NULL); if (!cmd) return -ENOMEM; sprintf(cmd->buf, "AT+CCFC=%s", buf); break; default: return -EINVAL; } if (cmd) return atcmd_submit(gu->gsmd, cmd); else return -ENOMEM;}static int null_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ gsmd_log(GSMD_DEBUG, "null cmd cb\n"); return 0;}/* PIN command callback. Gets called for response to AT+CPIN cmcd */static int pin_cmd_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; int ret = cmd->ret; /* Pass a GSM07.07 CME code directly, don't issue a new PIN * request because the client waits for a response to her * PIN submission rather than an event. */ return gsmd_ucmd_submit(gu, GSMD_MSG_PIN, GSMD_PIN_INPUT, cmd->id, sizeof(ret), &ret);}static const char *pin_type_names[__NUM_GSMD_PIN] = { [GSMD_PIN_READY] = "READY", [GSMD_PIN_SIM_PIN] = "SIM PIN", [GSMD_PIN_SIM_PUK] = "SIM PUK", [GSMD_PIN_PH_SIM_PIN] = "Phone-to-SIM PIN", [GSMD_PIN_PH_FSIM_PIN] = "Phone-to-very-first SIM PIN", [GSMD_PIN_PH_FSIM_PUK] = "Phone-to-very-first SIM PUK", [GSMD_PIN_SIM_PIN2] = "SIM PIN2", [GSMD_PIN_SIM_PUK2] = "SIM PUK2", [GSMD_PIN_PH_NET_PIN] = "Network personalization PIN", [GSMD_PIN_PH_NET_PUK] = "Network personalizaiton PUK", [GSMD_PIN_PH_NETSUB_PIN]= "Network subset personalisation PIN", [GSMD_PIN_PH_NETSUB_PUK]= "Network subset personalisation PUK", [GSMD_PIN_PH_SP_PIN] = "Service provider personalisation PIN", [GSMD_PIN_PH_SP_PUK] = "Service provider personalisation PUK", [GSMD_PIN_PH_CORP_PIN] = "Corporate personalisation PIN", [GSMD_PIN_PH_CORP_PUK] = "Corporate personalisation PUK",};static int get_cpin_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ enum gsmd_pin_type type; if (!strncmp(resp, "+CPIN: ", 7)) { unsigned int i; resp += 7; for (i = 0; i < __NUM_GSMD_PIN; i++) { if(!strcmp(resp,pin_type_names[i])) type = i; } } return gsmd_ucmd_submit(ctx, GSMD_MSG_PIN, GSMD_PIN_GET_STATUS, cmd->id, sizeof(type), &type);}static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len){ struct gsmd_pin *gp = (struct gsmd_pin *) ((void *)gph + sizeof(*gph)); struct gsmd_atcmd *cmd; switch (gph->msg_subtype) { case GSMD_PIN_INPUT: if (gph->len < sizeof(*gp) || len < sizeof(*gp)+sizeof(*gph)) return -EINVAL; gsmd_log(GSMD_DEBUG, "pin type=%u, pin='%s', newpin='%s'\n", gp->type, gp->pin, gp->newpin); cmd = atcmd_fill("AT+CPIN=\"", 9+GSMD_PIN_MAXLEN+3+GSMD_PIN_MAXLEN+2, &pin_cmd_cb, gu, 0, NULL); if (!cmd) return -ENOMEM; strlcat(cmd->buf, gp->pin, cmd->buflen); switch (gp->type) { case GSMD_PIN_SIM_PUK: case GSMD_PIN_SIM_PUK2: strlcat(cmd->buf, "\",\"", cmd->buflen); strlcat(cmd->buf, gp->newpin, cmd->buflen); break; default: break; } strlcat(cmd->buf, "\"", cmd->buflen); break; case GSMD_PIN_GET_STATUS: cmd = atcmd_fill("AT+CPIN?", 8 + 1, &get_cpin_cb, gu, 0, NULL); break; default: gsmd_log(GSMD_ERROR, "unknown pin type %u\n", gph->msg_subtype); return -EINVAL; } return atcmd_submit(gu->gsmd, cmd);}static int phone_powerup_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; int ret = cmd->ret; /* We need to verify if there is some error */ switch (ret) { case 0: gsmd_log(GSMD_DEBUG, "Radio powered-up\n"); gu->gsmd->dev_state.on = 1; break; default: /* something went wrong */ gsmd_log(GSMD_DEBUG, "Radio power-up failed\n"); break; } return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_POWERUP, cmd->id, sizeof(ret), &ret);}static int phone_powerdown_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ int ret = cmd->ret; return gsmd_ucmd_submit(ctx, GSMD_MSG_PHONE, GSMD_PHONE_POWERDOWN, cmd->id, sizeof(ret), &ret);}static int phone_power_status_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ DEBUGP("resp: %s\n", resp); if (!strncmp(resp, "+CFUN: ", 7)) resp += 7; return gsmd_ucmd_submit(ctx, GSMD_MSG_PHONE, GSMD_PHONE_POWER_STATUS, cmd->id, strlen(resp) + 1, resp);}static int phone_get_manuf_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp); if (!strncmp(resp, "+CGMI: ", 7)) resp += 7; return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_MANUF, cmd->id, strlen(resp) + 1, resp);}static int phone_get_model_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp); if (!strncmp(resp, "+CGMM: ", 7)) resp += 7; return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_MODEL, cmd->id, strlen(resp) + 1, resp);}static int phone_get_revision_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp); if (!strncmp(resp, "+CGMR: ", 7)) resp += 7; return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_REVISION, cmd->id, strlen(resp) + 1, resp);}static int phone_get_serial_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp); if (!strncmp(resp, "+CGSN: ", 7)) resp += 7; return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_SERIAL, cmd->id, strlen(resp) + 1, resp);}static int phone_get_battery_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; struct gsmd_battery_charge gbs; struct gsm_extrsp *er; DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp); er = extrsp_parse(gsmd_tallocs, resp); if(!er) return -ENOMEM; /* +CBC: 0,0 */ if((er->num_tokens == 2) && er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC && er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC ) { gbs.bcs = er->tokens[0].u.numeric; gbs.bcl = er->tokens[1].u.numeric; } talloc_free(er); return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_BATTERY, cmd -> id, sizeof(gbs), &gbs);}static int phone_vibrator_enable_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; int ret = cmd->ret; switch(ret) { case 0: gsmd_log(GSMD_DEBUG, "Vibrator enabled\n"); gu->gsmd->dev_state.vibrator = 1; break; default: gsmd_log(GSMD_DEBUG, "AT+CVIB=1 operation failed\n"); break; } return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_VIB_ENABLE, cmd->id, sizeof(ret), &ret);}static int phone_vibrator_disable_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ int ret = cmd->ret; return gsmd_ucmd_submit(ctx, GSMD_MSG_PHONE, GSMD_PHONE_VIB_DISABLE, cmd->id, sizeof(ret), &ret);} static int usock_rcv_phone(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len){ struct gsmd_atcmd *cmd; switch (gph->msg_subtype) { case GSMD_PHONE_POWERUP: cmd = atcmd_fill("AT+CFUN=1", 9+1, &phone_powerup_cb, gu, 0, NULL); break; case GSMD_PHONE_POWERDOWN: cmd = atcmd_fill("AT+CFUN=0", 9+1, &phone_powerdown_cb, gu, 0, NULL); gu->gsmd->dev_state.on = 0; break; case GSMD_PHONE_POWER_STATUS: cmd = atcmd_fill("AT+CFUN?", 8+1, &phone_power_status_cb, gu, 0, NULL); break; case GSMD_PHONE_GET_IMSI: return gsmd_ucmd_submit(gu, GSMD_MSG_PHONE, GSMD_PHONE_GET_IMSI, 0, strlen(gu->gsmd->imsi) + 1, gu->gsmd->imsi); break; case GSMD_PHONE_GET_MANUF: cmd = atcmd_fill("AT+CGMI", 7+1, &phone_get_manuf_cb, gu, 0, NULL); break; case GSMD_PHONE_GET_MODEL: cmd = atcmd_fill("AT+CGMM", 7+1, &phone_get_model_cb, gu, 0, NULL); break; case GSMD_PHONE_GET_REVISION: cmd = atcmd_fill("AT+CGMR", 7+1, &phone_get_revision_cb, gu, 0, NULL); break; case GSMD_PHONE_GET_SERIAL: cmd = atcmd_fill("AT+CGSN", 7+1, &phone_get_serial_cb, gu, 0, NULL); break; case GSMD_PHONE_GET_BATTERY: cmd = atcmd_fill("AT+CBC", 6+1, &phone_get_battery_cb, gu, 0, NULL); break; case GSMD_PHONE_VIB_ENABLE: cmd = atcmd_fill("AT+CVIB=1", 9+1, &phone_vibrator_enable_cb, gu, 0, NULL); break; case GSMD_PHONE_VIB_DISABLE: cmd = atcmd_fill("AT+CVIB=0", 9+1, &phone_vibrator_disable_cb, gu, 0, NULL); gu->gsmd->dev_state.vibrator = 0; break; default: return -EINVAL; } if (!cmd) return -ENOMEM; return atcmd_submit(gu->gsmd, cmd);}static int usock_rcv_modem(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len){ struct gsmd *g = gu->gsmd; if (g->machinepl->power) { g->machinepl->power(g, gph->msg_subtype); } return 0; }static int network_query_reg_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; struct gsm_extrsp *er; enum gsmd_netreg_state state; DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp); if (strncmp(resp, "+CREG: ", 7)) return -EINVAL; er = extrsp_parse(gsmd_tallocs, resp); if(!er) return -ENOMEM; //extrsp_dump(er); /* +CREG: <n>,<stat>[,<lac>,<ci>] */ if((er->num_tokens == 4 || er->num_tokens == 2 ) && er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC && er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC ) { state = er->tokens[1].u.numeric; } talloc_free(er); return gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_QUERY_REG, cmd->id, sizeof(state), &state);}static int network_vmail_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; struct gsmd_voicemail vmail; struct gsm_extrsp *er; int rc; int ret = cmd->ret; DEBUGP("cmd = '%s', resp: '%s'\n", cmd->buf, resp); if (cmd->buf[7] == '=') { /* response to set command */ rc = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_VMAIL_SET,cmd->id, sizeof(ret), &ret); } else { /* response to get command */ if (strncmp(resp, "+CSVM: ", 7)) return -EINVAL; resp += 7; er = extrsp_parse(gsmd_tallocs, resp); if(!er) return -ENOMEM; if(er->num_tokens == 3 && er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC && er->tokens[1].type == GSMD_ECMD_RTT_STRING && er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC) { vmail.enable = er->tokens[0].u.numeric; strlcpy(vmail.addr.number, er->tokens[1].u.string, GSMD_ADDR_MAXLEN+1); vmail.addr.type = er->tokens[2].u.numeric; } rc = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_VMAIL_GET, cmd->id, sizeof(vmail), &vmail); talloc_free(er); } return rc;}int gsmd_ucmd_submit(struct gsmd_user *gu, u_int8_t msg_type, u_int8_t msg_subtype, u_int16_t id, int len, const void *data){ struct gsmd_ucmd *ucmd = ucmd_alloc(len); if (!ucmd) return -ENOMEM; ucmd->hdr.version = GSMD_PROTO_VERSION; ucmd->hdr.msg_type = msg_type; ucmd->hdr.msg_subtype = msg_subtype; ucmd->hdr.len = len; ucmd->hdr.id = id; memcpy(ucmd->buf, data, len); usock_cmd_enqueue(ucmd, gu); return 0;}static int network_sigq_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?