usock.c.svn-base
来自「Linux下gsm/gprs modem的看守程序。支持短信发送与接受。」· SVN-BASE 代码 · 共 1,745 行 · 第 1/4 页
SVN-BASE
1,745 行
struct gsmd_signal_quality gsq; char *comma; gsq.rssi = atoi(resp + 6); comma = strchr(resp, ','); if (!comma ++) return -EIO; gsq.ber = atoi(comma); return gsmd_ucmd_submit(ctx, GSMD_MSG_NETWORK, GSMD_NETWORK_SIGQ_GET, cmd->id, sizeof(gsq), &gsq);}static int network_oper_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; const char *end, *opname; int format, s, ret; char *buf; /* Format: <mode>[,<format>,<oper>] */ /* In case we're not registered, return an empty string. */ if (sscanf(resp, "+COPS: %*i,%i,\"%n", &format, &s) <= 0) end = opname = resp; else { /* If the phone returned the opname in a short or numeric * format, then it probably doesn't know the operator's full * name or doesn't support it. Return any information we * have in this case. */ if (format != 0) gsmd_log(GSMD_NOTICE, "+COPS response in a format " " different than long alphanumeric - " " returning as is!\n"); opname = resp + s; end = strchr(opname, '"'); if (!end) return -EINVAL; } buf = strndup(opname, end - opname); ret = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_GET, cmd->id, end - opname + 1, buf); free(buf); return ret;}static int network_oper_n_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; char buf[16+1] = {'\0'}; struct gsm_extrsp *er; er = extrsp_parse(cmd, resp); if ( !er ) return -ENOMEM; //extrsp_dump(er); /* Format: <mode>[,<format>,<oper>] */ if ( er->num_tokens == 1 && er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC ) { /* In case we're not registered, return an empty string */ buf[0] = '\0'; } else if ( er->num_tokens >= 3 && er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC && er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC && er->tokens[2].type == GSMD_ECMD_RTT_STRING ) { strlcpy(buf, er->tokens[2].u.string, sizeof(buf)); } else { DEBUGP("Invalid Input : Parse error\n"); return -EINVAL; } talloc_free(er); return gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_N_GET, cmd->id, sizeof(buf), buf);}static int network_opers_parse(const char *str, struct gsmd_msg_oper **out){ int len = 0; struct gsm_extrsp *er; char buf[64]; char *head, *tail, *ptr; struct gsmd_msg_oper *out2; if (strncmp(str, "+COPS: ", 7)) return -EINVAL; /* * string ",," means the begginig of extended parameters and we * don't want to scan them for operators. */ ptr = strstr(str, ",,"); if(ptr) ptr[0] = '\0'; ptr = (char *) str; while (*str) { if ( *str == '(' && isdigit(*(str+1)) ) { len++; str+=2; } else str++; } *out = talloc_size(__gu_ctx, sizeof(struct gsmd_msg_oper) * (len + 1)); if (!out) return -ENOMEM; out2 = *out; str = ptr; while (*str) { if ( *str == '(' ) head = (char *) str; else if ( *str == ')' ) { tail = (char *) str; memset(buf, '\0', sizeof(buf)); strncpy(buf, head+1, (tail-head-1)); DEBUGP("buf: %s\n", buf); er = extrsp_parse(gsmd_tallocs, buf); if ( !er ) return -ENOMEM; //extrsp_dump(er); if ( er->num_tokens >= 4 && er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC && er->tokens[1].type == GSMD_ECMD_RTT_STRING && er->tokens[2].type == GSMD_ECMD_RTT_STRING && er->tokens[3].type == GSMD_ECMD_RTT_STRING ) { /* * +COPS=? +COPS: [list of supported (<stat>,long alphanumeric <oper> * ,short alphanumeric <oper>,numeric <oper>)s] */ out2->stat = er->tokens[0].u.numeric; strlcpy(out2->opname_longalpha, er->tokens[1].u.string, sizeof(out2->opname_longalpha)); strlcpy(out2->opname_shortalpha, er->tokens[2].u.string, sizeof(out2->opname_shortalpha)); strlcpy(out2->opname_num, er->tokens[3].u.string, sizeof(out2->opname_num)); } else { DEBUGP("Invalid Input : Parse error\n"); talloc_free(*out); return -EINVAL; } talloc_free(er); out2->is_last = 0; out2 ++; } str ++; } out2->is_last = 1; return len;}static int network_opers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; struct gsmd_msg_oper *buf = NULL; int len, ret; len = network_opers_parse(resp, &buf); if(len < 0) return len; /* error we got from network_opers_parse */ ret = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_LIST, cmd->id, sizeof(*buf) * (len + 1), buf); talloc_free(buf); return ret;}static int network_pref_opers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = (struct gsmd_user *) ctx; struct gsmd_msg_prefoper entry; int index; char opname[17]; if (cmd->ret && cmd->ret != -255) return 0; /* TODO: Send a response */ if (sscanf(resp, "+CPOL: %i,0,\"%16[^\"]\"", &index, opname) < 2) return -EINVAL; /* TODO: Send a response */ entry.index = index; entry.is_last = (cmd->ret == 0); memcpy(entry.opname_longalpha, opname, sizeof(entry.opname_longalpha)); return gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_LIST, cmd->id, sizeof(entry), &entry);}static int network_pref_num_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = (struct gsmd_user *) ctx; int min_index, max_index, size; if (cmd->ret) return 0; /* TODO: Send a response */ /* This is not a full general case, theoretically the range string * can include commas and more dashes, but we have no full parser for * ranges yet. */ if (sscanf(resp, "+CPOL: (%i-%i)", &min_index, &max_index) < 2) return -EINVAL; /* TODO: Send a response */ size = max_index - min_index + 1; return gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_PREF_SPACE, cmd->id, sizeof(size), &size);}static int network_ownnumbers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = (struct gsmd_user *) ctx; struct gsmd_own_number *num; int len, ret, type; char dummy; if (cmd->ret && cmd->ret != -255) return 0; /* TODO: Send a response */ if (sscanf(resp, "+CNUM: \"%*[^\"]\"%c%n", &dummy, &len) > 0) len -= strlen("+CNUM: \"\","); else len = 0; num = talloc_size(__gu_ctx, sizeof(*num) + len + 1); if (len) ret = sscanf(resp, "+CNUM: \"%[^\"]\",\"%32[^\"]\",%i,%*i,%i,", num->name, num->addr.number, &type, &num->service) - 1; else ret = sscanf(resp, "+CNUM: ,\"%32[^\"]\",%i,%*i,%i,", num->addr.number, &type, &num->service); if (ret < 2) { talloc_free(num); return -EINVAL; /* TODO: Send a response */ } if (ret < 3) num->service = GSMD_SERVICE_UNKNOWN; num->name[len] = 0; num->addr.type = type; num->is_last = (cmd->ret == 0); ret = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_GET_NUMBER, cmd->id, sizeof(*num) + len + 1, num); talloc_free(num); return ret;}static int usock_rcv_network(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, int len){ struct gsmd_atcmd *cmd; struct gsmd_voicemail *vmail = (struct gsmd_voicemail *) gph->data; gsmd_oper_numeric *oper = (gsmd_oper_numeric *) gph->data; char buffer[15 + sizeof(gsmd_oper_numeric)]; int cmdlen; switch (gph->msg_subtype) { case GSMD_NETWORK_REGISTER: if ((*oper)[0]) cmdlen = sprintf(buffer, "AT+COPS=1,2,\"%.*s\"", sizeof(gsmd_oper_numeric), (char *)oper); else cmdlen = sprintf(buffer, "AT+COPS=0"); cmd = atcmd_fill(buffer, cmdlen + 1, &null_cmd_cb, gu, 0, NULL); break; case GSMD_NETWORK_DEREGISTER: cmd = atcmd_fill("AT+COPS=2", 9+1, &null_cmd_cb, gu, 0, NULL); break; case GSMD_NETWORK_QUERY_REG: cmd = atcmd_fill("AT+CREG?", 8+1, &network_query_reg_cb, gu, 0, NULL); break; case GSMD_NETWORK_VMAIL_GET: cmd = atcmd_fill("AT+CSVM?", 8+1, &network_vmail_cb, gu, 0, NULL); break; case GSMD_NETWORK_VMAIL_SET: cmdlen = sprintf(buffer, "AT+CSVM=1,\"%s\",%d", vmail->addr.number, vmail->addr.type); cmd = atcmd_fill(buffer, cmdlen + 1, &network_vmail_cb, gu, 0, NULL); break; case GSMD_NETWORK_SIGQ_GET: cmd = atcmd_fill("AT+CSQ", 6+1, &network_sigq_cb, gu, 0, NULL); break; case GSMD_NETWORK_OPER_GET: /* Set long alphanumeric format */ atcmd_submit(gu->gsmd, atcmd_fill("AT+COPS=3,0", 11+1, &null_cmd_cb, gu, 0, NULL)); cmd = atcmd_fill("AT+COPS?", 8+1, &network_oper_cb, gu, 0, NULL); break; case GSMD_NETWORK_OPER_N_GET: /* Set numeric format */ atcmd_submit(gu->gsmd, atcmd_fill("AT+COPS=3,2", 11+1, &null_cmd_cb, gu, 0, NULL)); cmd = atcmd_fill("AT+COPS?", 8+1, &network_oper_n_cb, gu, 0, NULL); break; case GSMD_NETWORK_OPER_LIST: cmd = atcmd_fill("AT+COPS=?", 9+1, &network_opers_cb, gu, 0, NULL); break; case GSMD_NETWORK_PREF_LIST: /* Set long alphanumeric format */ atcmd_submit(gu->gsmd, atcmd_fill("AT+CPOL=,0", 10 + 1, &null_cmd_cb, gu, 0, NULL)); cmd = atcmd_fill("AT+CPOL?", 8 + 1, &network_pref_opers_cb, gu, 0, NULL); break; case GSMD_NETWORK_PREF_DEL: cmdlen = sprintf(buffer, "AT+CPOL=%i", *(int *) gph->data); cmd = atcmd_fill(buffer, cmdlen + 1, &null_cmd_cb, gu, 0, NULL); break; case GSMD_NETWORK_PREF_ADD: cmdlen = sprintf(buffer, "AT+CPOL=,2,\"%.*s\"", sizeof(gsmd_oper_numeric), (char *)oper); cmd = atcmd_fill(buffer, cmdlen + 1, &null_cmd_cb, gu, 0, NULL); break; case GSMD_NETWORK_PREF_SPACE: cmd = atcmd_fill("AT+CPOL=?", 9 + 1, &network_pref_num_cb, gu, 0, NULL); break; case GSMD_NETWORK_GET_NUMBER: cmd = atcmd_fill("AT+CNUM", 7 + 1, &network_ownnumbers_cb, gu, 0, NULL); break; default: return -EINVAL; } if (!cmd) return -ENOMEM; return atcmd_submit(gu->gsmd, cmd);}static int phonebook_find_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; struct gsmd_phonebooks gps; struct gsm_extrsp *er; DEBUGP("resp: %s\n", resp); er = extrsp_parse(cmd, resp); if ( !er ) return -ENOMEM; gps.is_last = (cmd->ret == 0 || cmd->ret == 4)? 1:0; if ( !strncmp(resp, "OK", 2) ) { /* The record is empty or could not read yet */ gps.pb.index = 0; } else if ( !strncmp(resp, "+CME", 4) ) { DEBUGP("== +CME error\n"); /* +CME ERROR: 21 */ gps.pb.index = 0 - atoi(strpbrk(resp, "0123456789")); } else if ( er->num_tokens == 4 && er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC && er->tokens[1].type == GSMD_ECMD_RTT_STRING && er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC && er->tokens[3].type == GSMD_ECMD_RTT_STRING ) { /* * [+CPBR: <index1>,<number>,<type>,<text>[[...] * <CR><LF>+CPBR: <index2>,<unmber>,<type>,<text>]] */ gps.pb.index = er->tokens[0].u.numeric; strlcpy(gps.pb.numb, er->tokens[1].u.string, GSMD_PB_NUMB_MAXLEN+1); gps.pb.type = er->tokens[2].u.numeric; strlcpy(gps.pb.text, er->tokens[3].u.string, GSMD_PB_TEXT_MAXLEN+1); } else { DEBUGP("Invalid Input : Parse error\n"); return -EINVAL; } talloc_free(er); return gsmd_ucmd_submit(gu, GSMD_MSG_PHONEBOOK, GSMD_PHONEBOOK_FIND, cmd->id, sizeof(gps), &gps);}static int phonebook_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp){ struct gsmd_user *gu = ctx; struct gsmd_phonebook gp; struct gsm_extrsp *er; DEBUGP("resp: %s\n", resp); er = extrsp_parse(cmd, resp); if ( !er ) return -ENOMEM; if ( !strncmp(resp, "OK", 2) ) { /* The record is empty or could not read yet */ gp.index = 0; } else if ( !strncmp(resp, "+CME", 4) ) { DEBUGP("+CME error\n"); /* +CME ERROR: 21 */ gp.index = 0 - atoi(strpbrk(resp, "0123456789")); } else if ( er->num_tokens == 4 && er->tokens[0].type == GSMD_ECMD_RTT_NUMERIC && er->tokens[1].type == GSMD_ECMD_RTT_STRING && er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC && er->tokens[3].type == GSMD_ECMD_RTT_STRING ) { /* * [+CPBR: <index1>,<number>,<type>,<text>[[...]
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?