@@ -465,6 +465,43 @@ static void modem_cmux_on_control_frame_ua(struct modem_cmux *cmux)
465465 k_event_post (& cmux -> event , MODEM_CMUX_EVENT_CONNECTED_BIT );
466466}
467467
468+ static void modem_cmux_respond_unsupported_cmd (struct modem_cmux * cmux )
469+ {
470+ struct modem_cmux_frame frame ;
471+ struct modem_cmux_command * cmd ;
472+
473+ memcpy (& frame , & cmux -> frame , sizeof (cmux -> frame ));
474+ if (modem_cmux_wrap_command (& cmd , frame .data , frame .data_len ) < 0 ) {
475+ LOG_WRN ("Invalid command" );
476+ return ;
477+ }
478+
479+ struct {
480+ struct modem_cmux_command nsc ;
481+ struct modem_cmux_command_type value ;
482+ } nsc_cmd = {
483+ .nsc = {
484+ .type = {
485+ .ea = 1 ,
486+ .cr = 0 ,
487+ .value = MODEM_CMUX_COMMAND_NSC ,
488+ },
489+ .length = {
490+ .ea = 1 ,
491+ .value = 1 ,
492+ },
493+ },
494+ .value = cmd -> type ,
495+ };
496+
497+ frame .data = (uint8_t * )& nsc_cmd ;
498+ frame .data_len = sizeof (nsc_cmd );
499+
500+ if (modem_cmux_transmit_cmd_frame (cmux , & frame ) == false) {
501+ LOG_WRN ("CMD response buffer overflow" );
502+ }
503+ }
504+
468505static void modem_cmux_on_control_frame_uih (struct modem_cmux * cmux )
469506{
470507 struct modem_cmux_command * command ;
@@ -501,6 +538,7 @@ static void modem_cmux_on_control_frame_uih(struct modem_cmux *cmux)
501538
502539 default :
503540 LOG_DBG ("Unknown control command" );
541+ modem_cmux_respond_unsupported_cmd (cmux );
504542 break ;
505543 }
506544}
@@ -524,6 +562,25 @@ static void modem_cmux_connect_response_transmit(struct modem_cmux *cmux)
524562 modem_cmux_transmit_cmd_frame (cmux , & frame );
525563}
526564
565+ static void modem_cmux_dm_response_transmit (struct modem_cmux * cmux )
566+ {
567+ if (cmux == NULL ) {
568+ return ;
569+ }
570+
571+ struct modem_cmux_frame frame = {
572+ .dlci_address = cmux -> frame .dlci_address ,
573+ .cr = cmux -> frame .cr ,
574+ .pf = 1 ,
575+ .type = MODEM_CMUX_FRAME_TYPE_DM ,
576+ .data = NULL ,
577+ .data_len = 0 ,
578+ };
579+
580+ LOG_DBG ("Send DM response" );
581+ modem_cmux_transmit_cmd_frame (cmux , & frame );
582+ }
583+
527584static void modem_cmux_on_control_frame_sabm (struct modem_cmux * cmux )
528585{
529586 modem_cmux_connect_response_transmit (cmux );
@@ -582,6 +639,13 @@ static struct modem_cmux_dlci *modem_cmux_find_dlci(struct modem_cmux *cmux)
582639 return NULL ;
583640}
584641
642+ static void modem_cmux_on_dlci_frame_dm (struct modem_cmux_dlci * dlci )
643+ {
644+ dlci -> state = MODEM_CMUX_DLCI_STATE_CLOSED ;
645+ modem_pipe_notify_closed (& dlci -> pipe );
646+ k_work_cancel_delayable (& dlci -> close_work );
647+ }
648+
585649static void modem_cmux_on_dlci_frame_ua (struct modem_cmux_dlci * dlci )
586650{
587651 switch (dlci -> state ) {
@@ -595,9 +659,8 @@ static void modem_cmux_on_dlci_frame_ua(struct modem_cmux_dlci *dlci)
595659 break ;
596660
597661 case MODEM_CMUX_DLCI_STATE_CLOSING :
598- dlci -> state = MODEM_CMUX_DLCI_STATE_CLOSED ;
599- modem_pipe_notify_closed (& dlci -> pipe );
600- k_work_cancel_delayable (& dlci -> close_work );
662+ /* Closing is handled same way in DM or as UA reply to DISC */
663+ modem_cmux_on_dlci_frame_dm (dlci );
601664 break ;
602665
603666 default :
@@ -606,6 +669,8 @@ static void modem_cmux_on_dlci_frame_ua(struct modem_cmux_dlci *dlci)
606669 }
607670}
608671
672+
673+
609674static void modem_cmux_on_dlci_frame_uih (struct modem_cmux_dlci * dlci )
610675{
611676 struct modem_cmux * cmux = dlci -> cmux ;
@@ -651,7 +716,7 @@ static void modem_cmux_on_dlci_frame_disc(struct modem_cmux_dlci *dlci)
651716 modem_cmux_connect_response_transmit (cmux );
652717
653718 if (dlci -> state != MODEM_CMUX_DLCI_STATE_OPEN ) {
654- LOG_DBG ( "Unexpected Disc frame" );
719+ modem_cmux_dm_response_transmit ( cmux );
655720 return ;
656721 }
657722
@@ -667,8 +732,9 @@ static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux)
667732
668733 dlci = modem_cmux_find_dlci (cmux );
669734 if (dlci == NULL ) {
670- LOG_WRN ("Ignoring frame intended for unconfigured DLCI %u." ,
735+ LOG_WRN ("Frame intended for unconfigured DLCI %u." ,
671736 cmux -> frame .dlci_address );
737+ modem_cmux_dm_response_transmit (cmux );
672738 return ;
673739 }
674740
@@ -688,7 +754,9 @@ static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux)
688754 case MODEM_CMUX_FRAME_TYPE_DISC :
689755 modem_cmux_on_dlci_frame_disc (dlci );
690756 break ;
691-
757+ case MODEM_CMUX_FRAME_TYPE_DM :
758+ modem_cmux_on_dlci_frame_dm (dlci );
759+ break ;
692760 default :
693761 LOG_WRN ("Unknown %s frame type" , "DLCI" );
694762 break ;
0 commit comments