diff options
author | Tilman Schmidt <tilman@imap.cc> | 2015-03-21 15:15:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-23 16:47:23 -0400 |
commit | 4df1e525afaaf363e72a4b441b674d5c78d08313 (patch) | |
tree | c8e6d07bd51a10af640955265f19bd2a71397f63 /drivers/isdn | |
parent | 6bf50114350856d0c90dc2bc3ecffc5df6dfbf15 (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.c | 126 |
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, ¶meter)) | 586 | kstrtoint(argv[curarg++], 10, ¶meter)) |
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 | } |