Changeset 2713
- Timestamp:
- 08/16/07 07:48:59 (6 years ago)
- Location:
- trunk/src/target/gsm
- Files:
-
- 7 edited
-
include/gsmd/usock.h (modified) (2 diffs)
-
include/libgsmd/misc.h (modified) (2 diffs)
-
src/gsmd/usock.c (modified) (4 diffs)
-
src/libgsmd/lgsm_internals.h (modified) (1 diff)
-
src/libgsmd/libgsmd_event.c (modified) (2 diffs)
-
src/libgsmd/libgsmd_network.c (modified) (2 diffs)
-
src/util/shell.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/target/gsm/include/gsmd/usock.h
r2711 r2713 67 67 GSMD_NETWORK_VMAIL_SET = 4, 68 68 GSMD_NETWORK_OPER_GET = 5, 69 GSMD_NETWORK_CIND_GET = 6, 69 GSMD_NETWORK_OPER_LIST = 6, 70 GSMD_NETWORK_CIND_GET = 7, 71 GSMD_NETWORK_DEREGISTER = 8, 70 72 }; 71 73 … … 359 361 } __attribute__ ((packed)); 360 362 363 /* Operator status from 3GPP TS 07.07, Clause 7.3 */ 364 enum gsmd_oper_status { 365 GSMD_OPER_UNKNOWN, 366 GSMD_OPER_AVAILABLE, 367 GSMD_OPER_CURRENT, 368 GSMD_OPER_FORBIDDEN, 369 }; 370 371 /* Theoretically numeric operator code is five digits long but some 372 * operators apparently use six digit codes. */ 373 typedef char gsmd_oper_numeric[6]; 374 375 struct gsmd_msg_oper { 376 enum gsmd_oper_status stat; 377 int is_last; 378 char opname_longalpha[16]; 379 char opname_shortalpha[8]; 380 gsmd_oper_numeric opname_num; 381 }; 382 361 383 struct gsmd_msg_hdr { 362 384 u_int8_t version; -
trunk/src/target/gsm/include/libgsmd/misc.h
r1765 r2713 10 10 11 11 extern int lgsm_phone_power(struct lgsm_handle *lh, int power); 12 13 enum lgsm_netreg_state {14 LGSM_NETREG_ST_NOTREG = 0,15 LGSM_NETREG_ST_REG_HOME = 1,16 LGSM_NETREG_ST_NOTREG_SEARCH = 2,17 LGSM_NETREG_ST_DENIED = 3,18 LGSM_NETREG_ST_UNKNOWN = 4,19 LGSM_NETREG_ST_REG_ROAMING = 5,20 };21 22 /* Get the current network registration status */23 extern int lgsm_get_netreg_state(struct lgsm_handle *lh,24 enum lgsm_netreg_state *state);25 26 extern int lgsm_netreg_register(struct lgsm_handle *lh, int oper);27 12 28 13 enum lgsm_info_type { … … 59 44 60 45 /* Operator Selection, Network Registration */ 61 /* TBD */ 46 extern int lgsm_oper_get(struct lgsm_handle *lh); 47 extern int lgsm_opers_get(struct lgsm_handle *lh); 48 extern int lgsm_netreg_register(struct lgsm_handle *lh, 49 gsmd_oper_numeric oper); 50 extern int lgsm_netreg_deregister(struct lgsm_handle *lh); 62 51 52 enum lgsm_netreg_state { 53 LGSM_NETREG_ST_NOTREG = 0, 54 LGSM_NETREG_ST_REG_HOME = 1, 55 LGSM_NETREG_ST_NOTREG_SEARCH = 2, 56 LGSM_NETREG_ST_DENIED = 3, 57 LGSM_NETREG_ST_UNKNOWN = 4, 58 LGSM_NETREG_ST_REG_ROAMING = 5, 59 }; 60 61 /* Get the current network registration status */ 62 extern int lgsm_get_netreg_state(struct lgsm_handle *lh, 63 enum lgsm_netreg_state *state); 63 64 64 65 /* CLIP, CLIR, COLP, Call Forwarding, Call Waiting, Call Deflecting */ -
trunk/src/target/gsm/src/gsmd/usock.c
r2711 r2713 350 350 351 351 gsq = (struct gsmd_signal_quality *) ucmd->buf; 352 gsq->rssi = atoi(resp );352 gsq->rssi = atoi(resp + 6); 353 353 comma = strchr(resp, ','); 354 354 if (!comma) { … … 363 363 } 364 364 365 #define GSMD_OPER_MAXLEN 16366 365 static int network_oper_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) 367 366 { 368 367 struct gsmd_user *gu = ctx; 369 368 struct gsmd_ucmd *ucmd; 370 char *comma, *opname; 371 372 ucmd = gsmd_ucmd_fill(GSMD_OPER_MAXLEN+1, GSMD_MSG_NETWORK, 373 GSMD_NETWORK_OPER_GET, 0); 374 if (!ucmd) 375 return -ENOMEM; 376 377 /* Format: <mode>[, <format>, <oper>] */ 378 comma = strchr(resp, ','); 379 if (!comma) 380 goto out_err; 381 382 if (atoi(comma+1) != 0) { 383 gsmd_log(GSMD_NOTICE, "COPS format !=0 not supported yet!\n"); 384 goto out_err; 385 } 386 comma = strchr(resp, ','); 387 if (!comma || *(comma+1) != '"') 388 goto out_err; 389 opname = comma+2; 390 391 memcpy(ucmd->buf, opname, strlen(opname-1)); 392 ucmd->buf[strlen(opname)] = '\0'; 393 394 usock_cmd_enqueue(ucmd, gu); 395 396 return 0; 397 398 out_err: 399 talloc_free(ucmd); 400 return -EIO; 369 const char *end, *opname; 370 int format, s; 371 372 /* Format: <mode>[,<format>,<oper>] */ 373 /* In case we're not registered, return an empty string. */ 374 if (sscanf(resp, "+COPS: %*i,%i,\"%n", &format, &s) <= 0) 375 end = opname = resp; 376 else { 377 /* If the phone returned the opname in a short or numeric 378 * format, then it probably doesn't know the operator's full 379 * name or doesn't support it. Return any information we 380 * have in this case. */ 381 if (format != 0) 382 gsmd_log(GSMD_NOTICE, "+COPS response in a format " 383 " different than long alphanumeric - " 384 " returning as is!\n"); 385 opname = resp + s; 386 end = strchr(opname, '"'); 387 if (!end) 388 return -EINVAL; 389 } 390 391 ucmd = gsmd_ucmd_fill(end - opname + 1, GSMD_MSG_NETWORK, 392 GSMD_NETWORK_OPER_GET, 0); 393 if (!ucmd) 394 return -ENOMEM; 395 396 memcpy(ucmd->buf, opname, end - opname); 397 ucmd->buf[end - opname] = '\0'; 398 399 usock_cmd_enqueue(ucmd, gu); 400 401 return 0; 402 } 403 404 static int network_opers_parse(const char *str, struct gsmd_msg_oper out[]) 405 { 406 int len = 0; 407 int stat, n; 408 if (strncmp(str, "+COPS: ", 7)) 409 goto final; 410 str += 7; 411 412 while (*str == '(') { 413 if (out) { 414 out->is_last = 0; 415 if (sscanf(str, 416 "(%i,\"%16[^\"]\"," 417 "\"%8[^\"]\",\"%6[0-9]\")%n", 418 &stat, 419 out->opname_longalpha, 420 out->opname_shortalpha, 421 out->opname_num, 422 &n) < 4) 423 goto final; 424 out->stat = stat; 425 } else 426 if (sscanf(str, 427 "(%*i,\"%*[^\"]\"," 428 "\"%*[^\"]\",\"%*[0-9]\")%n", 429 &n) < 0) 430 goto final; 431 if (n < 10 || str[n - 1] != ')') 432 goto final; 433 if (str[n] == ',') 434 n ++; 435 str += n; 436 len ++; 437 if (out) 438 out ++; 439 } 440 final: 441 if (out) 442 out->is_last = 1; 443 return len; 444 } 445 446 static int network_opers_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) 447 { 448 struct gsmd_user *gu = ctx; 449 struct gsmd_ucmd *ucmd; 450 int len; 451 452 len = network_opers_parse(resp, 0); 453 454 ucmd = gsmd_ucmd_fill(sizeof(struct gsmd_msg_oper) * (len + 1), 455 GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_LIST, 0); 456 if (!ucmd) 457 return -ENOMEM; 458 459 network_opers_parse(resp, (struct gsmd_msg_oper *) ucmd->buf); 460 usock_cmd_enqueue(ucmd, gu); 461 462 return 0; 401 463 } 402 464 … … 406 468 struct gsmd_atcmd *cmd; 407 469 struct gsmd_voicemail *vmail = (struct gsmd_voicemail *) gph->data; 470 gsmd_oper_numeric *oper = (gsmd_oper_numeric *) gph->data; 471 char buffer[15 + sizeof(gsmd_oper_numeric)]; 472 int cmdlen; 408 473 409 474 switch (gph->msg_subtype) { 410 475 case GSMD_NETWORK_REGISTER: 411 cmd = atcmd_fill("AT+COPS=0", 9+1, 412 &null_cmd_cb, gu, 0); 476 if ((*oper)[0]) 477 cmdlen = sprintf(buffer, "AT+COPS=1,2,\"%.*s\"", 478 sizeof(gsmd_oper_numeric), oper); 479 else 480 cmdlen = sprintf(buffer, "AT+COPS=0"); 481 cmd = atcmd_fill(buffer, cmdlen + 1, &null_cmd_cb, gu, 0); 482 break; 483 case GSMD_NETWORK_DEREGISTER: 484 cmd = atcmd_fill("AT+COPS=2", 9+1, &null_cmd_cb, gu, 0); 413 485 break; 414 486 case GSMD_NETWORK_VMAIL_GET: … … 422 494 break; 423 495 case GSMD_NETWORK_OPER_GET: 496 /* Set long alphanumeric format */ 497 atcmd_submit(gu->gsmd, atcmd_fill("AT+COPS=3,0", 11+1, 498 &null_cmd_cb, gu, 0)); 424 499 cmd = atcmd_fill("AT+COPS?", 8+1, &network_oper_cb, gu, 0); 500 break; 501 case GSMD_NETWORK_OPER_LIST: 502 cmd = atcmd_fill("AT+COPS=?", 9+1, &network_opers_cb, gu, 0); 425 503 break; 426 504 default: -
trunk/src/target/gsm/src/libgsmd/lgsm_internals.h
r114 r2713 3 3 4 4 #include <gsmd/usock.h> 5 #include <libgsmd/misc.h> 5 6 6 7 struct lgsm_handle { 7 8 int fd; 8 9 lgsm_msg_handler *handler[__NUM_GSMD_MSGS]; 10 enum lgsm_netreg_state netreg_state; 9 11 }; 10 12 -
trunk/src/target/gsm/src/libgsmd/libgsmd_event.c
r546 r2713 64 64 return -EINVAL; 65 65 66 switch (gmh->msg_subtype) { 67 case GSMD_EVT_NETREG: 68 lh->netreg_state = aux->u.netreg.state; 69 break; 70 } 71 66 72 if (evt_handlers[gmh->msg_subtype]) 67 73 return evt_handlers[gmh->msg_subtype](lh, gmh->msg_subtype, aux); … … 72 78 int lgsm_evt_init(struct lgsm_handle *lh) 73 79 { 80 lh->netreg_state = LGSM_NETREG_ST_NOTREG; 74 81 return lgsm_register_handler(lh, GSMD_MSG_EVENT, &evt_demux_msghandler); 75 82 } -
trunk/src/target/gsm/src/libgsmd/libgsmd_network.c
r547 r2713 33 33 #include "lgsm_internals.h" 34 34 35 int lgsm_netreg_register(struct lgsm_handle *lh, int oper) 35 /* Get the current network registration status */ 36 int lgsm_get_netreg_state(struct lgsm_handle *lh, 37 enum lgsm_netreg_state *state) 36 38 { 37 /* FIXME: implement oper selection */ 38 return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_REGISTER); 39 *state = lh->netreg_state; 40 } 41 42 int lgsm_oper_get(struct lgsm_handle *lh) 43 { 44 return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_GET); 45 } 46 47 int lgsm_opers_get(struct lgsm_handle *lh) 48 { 49 return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_LIST); 50 } 51 52 int lgsm_netreg_register(struct lgsm_handle *lh, gsmd_oper_numeric oper) 53 { 54 struct gsmd_msg_hdr *gmh; 55 56 gmh = lgsm_gmh_fill(GSMD_MSG_NETWORK, GSMD_NETWORK_REGISTER, 57 sizeof(gsmd_oper_numeric)); 58 if (!gmh) 59 return -ENOMEM; 60 61 memcpy(gmh->data, oper, sizeof(gsmd_oper_numeric)); 62 63 if (lgsm_send(lh, gmh) < gmh->len + sizeof(*gmh)) { 64 lgsm_gmh_free(gmh); 65 return -EIO; 66 } 67 68 lgsm_gmh_free(gmh); 69 return 0; 70 } 71 72 int lgsm_netreg_deregister(struct lgsm_handle *lh) 73 { 74 return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_DEREGISTER); 39 75 } 40 76 … … 43 79 return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_SIGQ_GET); 44 80 } 45 46 int lgsmd_operator_name(struct lgsm_handle *lh)47 {48 return lgsm_send_simple(lh, GSMD_MSG_NETWORK, GSMD_NETWORK_OPER_GET);49 } -
trunk/src/target/gsm/src/util/shell.c
r2710 r2713 172 172 } 173 173 174 /* this is the handler for responses to network/operator commands */ 175 static int net_msghandler(struct lgsm_handle *lh, struct gsmd_msg_hdr *gmh) 176 { 177 const struct gsmd_signal_quality *sq = (struct gsmd_signal_quality *) 178 ((void *) gmh + sizeof(*gmh)); 179 const char *oper = (char *) gmh + sizeof(*gmh); 180 const struct gsmd_msg_oper *opers = (struct gsmd_msg_oper *) 181 ((void *) gmh + sizeof(*gmh)); 182 static const char *oper_stat[] = { 183 [GSMD_OPER_UNKNOWN] = "of unknown status", 184 [GSMD_OPER_AVAILABLE] = "available", 185 [GSMD_OPER_CURRENT] = "our current operator", 186 [GSMD_OPER_FORBIDDEN] = "forbidden", 187 }; 188 189 switch (gmh->msg_subtype) { 190 case GSMD_NETWORK_SIGQ_GET: 191 if (sq->rssi == 99) 192 printf("Signal undetectable\n"); 193 else 194 printf("Signal quality %i dBm\n", -113 + sq->rssi * 2); 195 if (sq->ber == 99) 196 printf("Error rate undetectable\n"); 197 else 198 printf("Bit error rate %i\n", sq->ber); 199 break; 200 case GSMD_NETWORK_OPER_GET: 201 if (oper[0]) 202 printf("Our current operator is %s\n", oper); 203 else 204 printf("No current operator\n"); 205 break; 206 case GSMD_NETWORK_OPER_LIST: 207 for (; !opers->is_last; opers ++) 208 printf("%8.*s %16.*s, %.*s for short, is %s\n", 209 sizeof(opers->opname_num), 210 opers->opname_num, 211 sizeof(opers->opname_longalpha), 212 opers->opname_longalpha, 213 sizeof(opers->opname_shortalpha), 214 opers->opname_shortalpha, 215 oper_stat[opers->stat]); 216 break; 217 default: 218 return -EINVAL; 219 } 220 } 221 174 222 static int shell_help(void) 175 223 { … … 179 227 "\tO\tPower On\n" 180 228 "\to\tPower Off\n" 181 "\tR\tRegister Network\n" 229 "\tr\tRegister to network\n" 230 "\tR\tRegister to given operator (R=number)\n" 182 231 "\tU\tUnregister from netowrk\n" 232 "\tP\tPrint current operator\n" 233 "\tL\tDetect available operators\n" 234 "\tQ\tRead signal quality\n" 183 235 "\tT\tSend DTMF Tone\n" 184 236 "\tpd\tPB Delete (pb=index)\n" … … 209 261 lgsm_register_handler(lgsmh, GSMD_MSG_PHONEBOOK, &pb_msghandler); 210 262 lgsm_register_handler(lgsmh, GSMD_MSG_SMS, &sms_msghandler); 263 lgsm_register_handler(lgsmh, GSMD_MSG_NETWORK, &net_msghandler); 211 264 212 265 fcntl(0, F_SETFD, O_NONBLOCK); … … 273 326 printf("Power-Off\n"); 274 327 lgsm_phone_power(lgsmh, 0); 275 } else if (!strcmp(buf, " R")) {328 } else if (!strcmp(buf, "r")) { 276 329 printf("Register\n"); 277 lgsm_netreg_register(lgsmh, 0); 330 lgsm_netreg_register(lgsmh, "\0 "); 331 } else if (buf[0] == 'R') { 332 printf("Register to operator\n"); 333 ptr = strchr(buf, '='); 334 if (!ptr || strlen(ptr) < 6) 335 printf("No.\n"); 336 else 337 lgsm_netreg_register(lgsmh, ptr + 1); 278 338 } else if (!strcmp(buf, "U")) { 279 339 printf("Unregister\n"); 280 lgsm_netreg_register(lgsmh, 2); 340 lgsm_netreg_deregister(lgsmh); 341 } else if (!strcmp(buf, "P")) { 342 printf("Read current opername\n"); 343 lgsm_oper_get(lgsmh); 344 } else if (!strcmp(buf, "L")) { 345 printf("List operators\n"); 346 lgsm_opers_get(lgsmh); 347 } else if (!strcmp(buf, "Q")) { 348 printf("Signal strength\n"); 349 lgsm_signal_quality(lgsmh); 281 350 } else if (!strcmp(buf, "q")) { 282 351 exit(0);
Note: See TracChangeset
for help on using the changeset viewer.
