summaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorTilman Schmidt <tilman@imap.cc>2015-03-21 15:15:32 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-23 16:47:23 -0400
commit4df1e525afaaf363e72a4b441b674d5c78d08313 (patch)
treec8e6d07bd51a10af640955265f19bd2a71397f63 /drivers/isdn
parent6bf50114350856d0c90dc2bc3ecffc5df6dfbf15 (diff)
isdn/gigaset: restructure modem response parser (2)
Separate literal string handling from main parser loop. Signed-off-by: Tilman Schmidt <tilman@imap.cc> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/gigaset/ev-layer.c126
1 files changed, 57 insertions, 69 deletions
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index d1b84f488834..b2a1fb1326ae 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -455,91 +455,79 @@ void gigaset_handle_modem_response(struct cardstate *cs)
455 const struct resp_type_t *rt; 455 const struct resp_type_t *rt;
456 const struct zsau_resp_t *zr; 456 const struct zsau_resp_t *zr;
457 int curarg; 457 int curarg;
458 int resp_code;
459 int param_type;
460 int abort; 458 int abort;
461 size_t len;
462 int cid, parameter; 459 int cid, parameter;
463 int rawstring;
464 460
465 len = cs->cbytes; 461 if (!cs->cbytes) {
466 if (!len) {
467 /* ignore additional LFs/CRs (M10x config mode or cx100) */ 462 /* ignore additional LFs/CRs (M10x config mode or cx100) */
468 gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[0]); 463 gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[0]);
469 return; 464 return;
470 } 465 }
471 cs->respdata[len] = 0; 466 cs->respdata[cs->cbytes] = 0;
472 argv[0] = cs->respdata; 467
473 params = 1;
474 if (cs->at_state.getstring) { 468 if (cs->at_state.getstring) {
475 /* getstring only allowed without cid at the moment */ 469 /* state machine wants next line verbatim */
476 cs->at_state.getstring = 0; 470 cs->at_state.getstring = 0;
477 rawstring = 1; 471 ptr = kstrdup(cs->respdata, GFP_ATOMIC);
478 cid = 0; 472 gig_dbg(DEBUG_EVENT, "string==%s", ptr ? ptr : "NULL");
479 } else { 473 add_cid_event(cs, 0, RSP_STRING, ptr, 0);
480 /* parse line */ 474 return;
481 for (i = 0; i < len; i++) 475 }
482 switch (cs->respdata[i]) {
483 case ';':
484 case ',':
485 case '=':
486 if (params > MAX_REC_PARAMS) {
487 dev_warn(cs->dev,
488 "too many parameters in response\n");
489 /* need last parameter (might be CID) */
490 params--;
491 }
492 argv[params++] = cs->respdata + i + 1;
493 }
494 476
495 rawstring = 0; 477 /* parse line */
496 cid = params > 1 ? cid_of_response(argv[params - 1]) : 0; 478 argv[0] = cs->respdata;
497 if (cid < 0) { 479 params = 1;
498 gigaset_add_event(cs, &cs->at_state, RSP_INVAL, 480 for (i = 0; i < cs->cbytes; i++)
499 NULL, 0, NULL); 481 switch (cs->respdata[i]) {
500 return; 482 case ';':
483 case ',':
484 case '=':
485 if (params > MAX_REC_PARAMS) {
486 dev_warn(cs->dev,
487 "too many parameters in response\n");
488 /* need last parameter (might be CID) */
489 params--;
490 }
491 argv[params++] = cs->respdata + i + 1;
501 } 492 }
502 493
503 for (j = 1; j < params; ++j) 494 cid = params > 1 ? cid_of_response(argv[params - 1]) : 0;
504 argv[j][-1] = 0; 495 if (cid < 0) {
496 gigaset_add_event(cs, &cs->at_state, RSP_INVAL, NULL, 0, NULL);
497 return;
498 }
499
500 for (j = 1; j < params; ++j)
501 argv[j][-1] = 0;
505 502
506 gig_dbg(DEBUG_EVENT, "CMD received: %s", argv[0]); 503 gig_dbg(DEBUG_EVENT, "CMD received: %s", argv[0]);
507 if (cid) { 504 if (cid) {
508 --params; 505 --params;
509 gig_dbg(DEBUG_EVENT, "CID: %s", argv[params]); 506 gig_dbg(DEBUG_EVENT, "CID: %s", argv[params]);
510 }
511 gig_dbg(DEBUG_EVENT, "available params: %d", params - 1);
512 for (j = 1; j < params; j++)
513 gig_dbg(DEBUG_EVENT, "param %d: %s", j, argv[j]);
514 } 507 }
508 gig_dbg(DEBUG_EVENT, "available params: %d", params - 1);
509 for (j = 1; j < params; j++)
510 gig_dbg(DEBUG_EVENT, "param %d: %s", j, argv[j]);
515 511
516 abort = 1; 512 abort = 1;
517 curarg = 0; 513 curarg = 0;
518 while (curarg < params) { 514 while (curarg < params) {
519 if (rawstring) { 515 for (rt = resp_type; rt->response; ++rt)
520 resp_code = RSP_STRING; 516 if (!strcmp(argv[curarg], rt->response))
521 param_type = RT_STRING;
522 } else {
523 for (rt = resp_type; rt->response; ++rt)
524 if (!strcmp(argv[curarg], rt->response))
525 break;
526
527 if (!rt->response) {
528 add_cid_event(cs, 0, RSP_NONE, NULL, 0);
529 gig_dbg(DEBUG_EVENT,
530 "unknown modem response: '%s'\n",
531 argv[curarg]);
532 break; 517 break;
533 }
534 518
535 resp_code = rt->resp_code; 519 if (!rt->response) {
536 param_type = rt->type; 520 add_cid_event(cs, 0, RSP_NONE, NULL, 0);
537 ++curarg; 521 gig_dbg(DEBUG_EVENT, "unknown modem response: '%s'\n",
522 argv[curarg]);
523 break;
538 } 524 }
539 525
540 switch (param_type) { 526 ++curarg;
527
528 switch (rt->type) {
541 case RT_NOTHING: 529 case RT_NOTHING:
542 add_cid_event(cs, cid, resp_code, NULL, 0); 530 add_cid_event(cs, cid, rt->resp_code, NULL, 0);
543 break; 531 break;
544 case RT_RING: 532 case RT_RING:
545 if (!cid) { 533 if (!cid) {
@@ -548,13 +536,13 @@ void gigaset_handle_modem_response(struct cardstate *cs)
548 add_cid_event(cs, 0, RSP_INVAL, NULL, 0); 536 add_cid_event(cs, 0, RSP_INVAL, NULL, 0);
549 abort = 1; 537 abort = 1;
550 } else { 538 } else {
551 add_cid_event(cs, 0, resp_code, NULL, cid); 539 add_cid_event(cs, 0, rt->resp_code, NULL, cid);
552 abort = 0; 540 abort = 0;
553 } 541 }
554 break; 542 break;
555 case RT_ZSAU: 543 case RT_ZSAU:
556 if (curarg >= params) { 544 if (curarg >= params) {
557 add_cid_event(cs, cid, resp_code, NULL, 545 add_cid_event(cs, cid, rt->resp_code, NULL,
558 ZSAU_NONE); 546 ZSAU_NONE);
559 break; 547 break;
560 } 548 }
@@ -565,7 +553,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
565 dev_warn(cs->dev, 553 dev_warn(cs->dev,
566 "%s: unknown parameter %s after ZSAU\n", 554 "%s: unknown parameter %s after ZSAU\n",
567 __func__, argv[curarg]); 555 __func__, argv[curarg]);
568 add_cid_event(cs, cid, resp_code, NULL, zr->code); 556 add_cid_event(cs, cid, rt->resp_code, NULL, zr->code);
569 ++curarg; 557 ++curarg;
570 break; 558 break;
571 case RT_STRING: 559 case RT_STRING:
@@ -578,7 +566,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
578 ptr = NULL; 566 ptr = NULL;
579 } 567 }
580 gig_dbg(DEBUG_EVENT, "string==%s", ptr ? ptr : "NULL"); 568 gig_dbg(DEBUG_EVENT, "string==%s", ptr ? ptr : "NULL");
581 add_cid_event(cs, cid, resp_code, ptr, 0); 569 add_cid_event(cs, cid, rt->resp_code, ptr, 0);
582 break; 570 break;
583 case RT_ZCAU: 571 case RT_ZCAU:
584 parameter = -1; 572 parameter = -1;
@@ -591,15 +579,15 @@ void gigaset_handle_modem_response(struct cardstate *cs)
591 parameter = (type << 8) | value; 579 parameter = (type << 8) | value;
592 } else 580 } else
593 curarg = params - 1; 581 curarg = params - 1;
594 add_cid_event(cs, cid, resp_code, NULL, parameter); 582 add_cid_event(cs, cid, rt->resp_code, NULL, parameter);
595 break; 583 break;
596 case RT_NUMBER: 584 case RT_NUMBER:
597 if (curarg >= params || 585 if (curarg >= params ||
598 kstrtoint(argv[curarg++], 10, &parameter)) 586 kstrtoint(argv[curarg++], 10, &parameter))
599 parameter = -1; 587 parameter = -1;
600 gig_dbg(DEBUG_EVENT, "parameter==%d", parameter); 588 gig_dbg(DEBUG_EVENT, "parameter==%d", parameter);
601 add_cid_event(cs, cid, resp_code, NULL, parameter); 589 add_cid_event(cs, cid, rt->resp_code, NULL, parameter);
602 if (resp_code == RSP_ZDLE) 590 if (rt->resp_code == RSP_ZDLE)
603 cs->dle = parameter; 591 cs->dle = parameter;
604 break; 592 break;
605 } 593 }