@@ -338,6 +338,7 @@ static bool modem_cmux_transmit_cmd_frame(struct modem_cmux *cmux,
338
338
339
339
if (space < MODEM_CMUX_CMD_FRAME_SIZE_MAX ) {
340
340
k_mutex_unlock (& cmux -> transmit_rb_lock );
341
+ LOG_WRN ("CMD buffer overflow" );
341
342
return false;
342
343
}
343
344
@@ -475,6 +476,41 @@ static void modem_cmux_on_control_frame_ua(struct modem_cmux *cmux)
475
476
k_event_post (& cmux -> event , MODEM_CMUX_EVENT_CONNECTED_BIT );
476
477
}
477
478
479
+ static void modem_cmux_respond_unsupported_cmd (struct modem_cmux * cmux )
480
+ {
481
+ struct modem_cmux_frame frame = cmux -> frame ;
482
+ struct modem_cmux_command * cmd ;
483
+
484
+ if (modem_cmux_wrap_command (& cmd , frame .data , frame .data_len ) < 0 ) {
485
+ LOG_WRN ("Invalid command" );
486
+ return ;
487
+ }
488
+
489
+ struct {
490
+ /* 3GPP TS 27.010: 5.4.6.3.8 Non Supported Command Response (NSC) */
491
+ struct modem_cmux_command nsc ;
492
+ struct modem_cmux_command_type value ;
493
+ } nsc_cmd = {
494
+ .nsc = {
495
+ .type = {
496
+ .ea = 1 ,
497
+ .cr = 0 ,
498
+ .value = MODEM_CMUX_COMMAND_NSC ,
499
+ },
500
+ .length = {
501
+ .ea = 1 ,
502
+ .value = 1 ,
503
+ },
504
+ },
505
+ .value = cmd -> type ,
506
+ };
507
+
508
+ frame .data = (uint8_t * )& nsc_cmd ;
509
+ frame .data_len = sizeof (nsc_cmd );
510
+
511
+ modem_cmux_transmit_cmd_frame (cmux , & frame );
512
+ }
513
+
478
514
static void modem_cmux_on_control_frame_uih (struct modem_cmux * cmux )
479
515
{
480
516
struct modem_cmux_command * command ;
@@ -511,6 +547,7 @@ static void modem_cmux_on_control_frame_uih(struct modem_cmux *cmux)
511
547
512
548
default :
513
549
LOG_DBG ("Unknown control command" );
550
+ modem_cmux_respond_unsupported_cmd (cmux );
514
551
break ;
515
552
}
516
553
}
@@ -534,6 +571,26 @@ static void modem_cmux_connect_response_transmit(struct modem_cmux *cmux)
534
571
modem_cmux_transmit_cmd_frame (cmux , & frame );
535
572
}
536
573
574
+ static void modem_cmux_dm_response_transmit (struct modem_cmux * cmux )
575
+ {
576
+ if (cmux == NULL ) {
577
+ return ;
578
+ }
579
+
580
+ /* 3GPP TS 27.010: 5.3.3 Disconnected Mode (DM) response */
581
+ struct modem_cmux_frame frame = {
582
+ .dlci_address = cmux -> frame .dlci_address ,
583
+ .cr = cmux -> frame .cr ,
584
+ .pf = 1 ,
585
+ .type = MODEM_CMUX_FRAME_TYPE_DM ,
586
+ .data = NULL ,
587
+ .data_len = 0 ,
588
+ };
589
+
590
+ LOG_DBG ("Send DM response" );
591
+ modem_cmux_transmit_cmd_frame (cmux , & frame );
592
+ }
593
+
537
594
static void modem_cmux_on_control_frame_sabm (struct modem_cmux * cmux )
538
595
{
539
596
modem_cmux_connect_response_transmit (cmux );
@@ -593,6 +650,13 @@ static struct modem_cmux_dlci *modem_cmux_find_dlci(struct modem_cmux *cmux)
593
650
return NULL ;
594
651
}
595
652
653
+ static void modem_cmux_on_dlci_frame_dm (struct modem_cmux_dlci * dlci )
654
+ {
655
+ dlci -> state = MODEM_CMUX_DLCI_STATE_CLOSED ;
656
+ modem_pipe_notify_closed (& dlci -> pipe );
657
+ k_work_cancel_delayable (& dlci -> close_work );
658
+ }
659
+
596
660
static void modem_cmux_on_dlci_frame_ua (struct modem_cmux_dlci * dlci )
597
661
{
598
662
switch (dlci -> state ) {
@@ -608,9 +672,7 @@ static void modem_cmux_on_dlci_frame_ua(struct modem_cmux_dlci *dlci)
608
672
609
673
case MODEM_CMUX_DLCI_STATE_CLOSING :
610
674
LOG_DBG ("DLCI %u closed" , dlci -> dlci_address );
611
- dlci -> state = MODEM_CMUX_DLCI_STATE_CLOSED ;
612
- modem_pipe_notify_closed (& dlci -> pipe );
613
- k_work_cancel_delayable (& dlci -> close_work );
675
+ modem_cmux_on_dlci_frame_dm (dlci );
614
676
break ;
615
677
616
678
default :
@@ -619,6 +681,8 @@ static void modem_cmux_on_dlci_frame_ua(struct modem_cmux_dlci *dlci)
619
681
}
620
682
}
621
683
684
+
685
+
622
686
static void modem_cmux_on_dlci_frame_uih (struct modem_cmux_dlci * dlci )
623
687
{
624
688
struct modem_cmux * cmux = dlci -> cmux ;
@@ -665,7 +729,7 @@ static void modem_cmux_on_dlci_frame_disc(struct modem_cmux_dlci *dlci)
665
729
modem_cmux_connect_response_transmit (cmux );
666
730
667
731
if (dlci -> state != MODEM_CMUX_DLCI_STATE_OPEN ) {
668
- LOG_DBG ( "Unexpected Disc frame" );
732
+ modem_cmux_dm_response_transmit ( cmux );
669
733
return ;
670
734
}
671
735
@@ -682,8 +746,9 @@ static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux)
682
746
683
747
dlci = modem_cmux_find_dlci (cmux );
684
748
if (dlci == NULL ) {
685
- LOG_WRN ("Ignoring frame intended for unconfigured DLCI %u." ,
749
+ LOG_WRN ("Frame intended for unconfigured DLCI %u." ,
686
750
cmux -> frame .dlci_address );
751
+ modem_cmux_dm_response_transmit (cmux );
687
752
return ;
688
753
}
689
754
@@ -703,7 +768,9 @@ static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux)
703
768
case MODEM_CMUX_FRAME_TYPE_DISC :
704
769
modem_cmux_on_dlci_frame_disc (dlci );
705
770
break ;
706
-
771
+ case MODEM_CMUX_FRAME_TYPE_DM :
772
+ modem_cmux_on_dlci_frame_dm (dlci );
773
+ break ;
707
774
default :
708
775
LOG_WRN ("Unknown %s frame type (%d, DLCI %d)" , "DLCI" , cmux -> frame .type ,
709
776
cmux -> frame .dlci_address );
0 commit comments