@@ -52,6 +52,8 @@ const char LTE_SHIELD_COMMAND_MNO[] = "+UMNOPROF"; // MNO (mobile network operat
52
52
const char LTE_SHIELD_SIGNAL_QUALITY[] = " +CSQ" ;
53
53
const char LTE_SHIELD_REGISTRATION_STATUS[] = " +CREG" ;
54
54
const char LTE_SHIELD_MESSAGE_PDP_DEF[] = " +CGDCONT" ;
55
+ const char LTE_SHIELD_MESSAGE_ENTER_PPP[] = " D" ;
56
+ const char LTE_SHIELD_OPERATOR_SELECTION[] = " +COPS" ;
55
57
// V24 control and V25ter (UART interface)
56
58
const char LTE_SHIELD_COMMAND_BAUD[] = " +IPR" ; // Baud rate
57
59
// ### GPIO
@@ -577,7 +579,6 @@ boolean LTE_Shield::setNetwork(mobile_network_operator_t mno)
577
579
578
580
// Check currently set MNO
579
581
if (getMno (¤tMno) != LTE_SHIELD_ERROR_SUCCESS) {
580
- Serial.println (" Error getting MNO" );
581
582
return false ;
582
583
}
583
584
if (currentMno == mno)
@@ -586,18 +587,15 @@ boolean LTE_Shield::setNetwork(mobile_network_operator_t mno)
586
587
}
587
588
588
589
if (functionality (MINIMUM_FUNCTIONALITY) != LTE_SHIELD_ERROR_SUCCESS) {
589
- Serial.println (" Error setting functionality" );
590
590
return false ;
591
591
}
592
592
593
593
if (setMno (mno) != LTE_SHIELD_ERROR_SUCCESS) {
594
- Serial.println (" Error setting MNO" );
595
594
return false ;
596
595
}
597
596
598
597
if (reset () != LTE_SHIELD_ERROR_SUCCESS)
599
598
{
600
- Serial.println (" Error resetting" );
601
599
return false ;
602
600
}
603
601
@@ -651,11 +649,285 @@ LTE_Shield_error_t LTE_Shield::setAPN(String apn, uint8_t cid, LTE_Shield_pdp_ty
651
649
652
650
err = sendCommandWithResponse (command, LTE_SHIELD_RESPONSE_OK, NULL ,
653
651
LTE_SHIELD_STANDARD_RESPONSE_TIMEOUT);
654
- // Serial.println("Set APN: " + String(command));
652
+
653
+ free (command);
654
+
655
+ return err;
656
+ }
657
+
658
+ LTE_Shield_error_t LTE_Shield::getAPN (String * apn, IPAddress * ip)
659
+ {
660
+ LTE_Shield_error_t err;
661
+ char * command;
662
+ char * response;
663
+ char * searchPtr;
664
+ uint8_t ipOctets[4 ];
665
+
666
+ command = lte_calloc_char (strlen (LTE_SHIELD_MESSAGE_PDP_DEF) + 3 );
667
+ if (command == NULL ) return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
668
+ sprintf (command, " %s?" , LTE_SHIELD_MESSAGE_PDP_DEF);
669
+
670
+ response = lte_calloc_char (128 );
671
+ if (response == NULL )
672
+ {
673
+ free (command);
674
+ return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
675
+ }
676
+
677
+ err = sendCommandWithResponse (command, LTE_SHIELD_RESPONSE_OK, response,
678
+ LTE_SHIELD_STANDARD_RESPONSE_TIMEOUT);
679
+
680
+ if (err == LTE_SHIELD_ERROR_SUCCESS)
681
+ {
682
+ // Example: +CGDCONT: 1,"IP","hologram","10.170.241.191",0,0,0,0
683
+ searchPtr = strstr (response, " +CGDCONT: " );
684
+ if (searchPtr != NULL )
685
+ {
686
+ searchPtr += strlen (" +CGDCONT: " );
687
+ // Search to the third double-quote
688
+ for (int i = 0 ; i < 3 ; i ++)
689
+ {
690
+ searchPtr = strchr (++searchPtr, ' \" ' );
691
+ }
692
+ if (searchPtr != NULL )
693
+ {
694
+ // Fill in the APN:
695
+ searchPtr = strchr (searchPtr, ' \" ' ); // Move to first quote
696
+ while ((*(++searchPtr) != ' \" ' ) && (searchPtr != ' \0 ' ))
697
+ {
698
+ apn->concat (*(searchPtr));
699
+ }
700
+ // Now get the IP:
701
+ if (searchPtr != NULL )
702
+ {
703
+ int scanned = sscanf (searchPtr, " \" ,\" %hhu.%hhu.%hhu.%hhu\" " ,
704
+ &ipOctets[0 ], &ipOctets[1 ], &ipOctets[2 ], &ipOctets[3 ]);
705
+ if (scanned == 4 )
706
+ {
707
+ for (int octet = 0 ; octet < 4 ; octet++)
708
+ {
709
+ (*ip)[octet] = ipOctets[octet];
710
+ }
711
+ }
712
+ }
713
+ }
714
+ }
715
+ else
716
+ {
717
+ err = LTE_SHIELD_ERROR_UNEXPECTED_RESPONSE;
718
+ }
719
+ }
720
+
721
+ free (command);
722
+ free (response);
723
+
724
+ return err;
725
+ }
726
+
727
+ const char * PPP_L2P[5 ] = {
728
+ " " ,
729
+ " PPP" ,
730
+ " M-HEX" ,
731
+ " M-RAW_IP" ,
732
+ " M-OPT-PPP" ,
733
+ };
734
+
735
+ LTE_Shield_error_t LTE_Shield::enterPPP (uint8_t cid, char dialing_type_char,
736
+ unsigned long dialNumber, LTE_Shield::LTE_Shield_l2p_t l2p)
737
+ {
738
+ LTE_Shield_error_t err;
739
+ char * command;
740
+
741
+ if ((dialing_type_char != 0 ) && (dialing_type_char != ' T' ) &&
742
+ (dialing_type_char != ' P' ))
743
+ {
744
+ return LTE_SHIELD_ERROR_UNEXPECTED_PARAM;
745
+ }
746
+
747
+ command = lte_calloc_char (strlen (LTE_SHIELD_MESSAGE_ENTER_PPP) + 32 );
748
+ if (command == NULL ) return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
749
+ if (dialing_type_char != 0 )
750
+ {
751
+ sprintf (command, " %s%c*%lu**%s*%hhu#" , LTE_SHIELD_MESSAGE_ENTER_PPP, dialing_type_char,
752
+ dialNumber, PPP_L2P[l2p], cid);
753
+ }
754
+ else
755
+ {
756
+ sprintf (command, " %s*%lu**%s*%hhu#" , LTE_SHIELD_MESSAGE_ENTER_PPP,
757
+ dialNumber, PPP_L2P[l2p], cid);
758
+ }
759
+
760
+ err = sendCommandWithResponse (command, LTE_SHIELD_RESPONSE_OK, NULL ,
761
+ LTE_SHIELD_STANDARD_RESPONSE_TIMEOUT);
762
+
763
+ free (command);
764
+ return err;
765
+ }
766
+
767
+ uint8_t LTE_Shield::getOperators (struct operator_stats * opRet, int maxOps)
768
+ {
769
+ LTE_Shield_error_t err;
770
+ char * command;
771
+ char * response;
772
+ uint8_t opsSeen = 0 ;
773
+
774
+ command = lte_calloc_char (strlen (LTE_SHIELD_OPERATOR_SELECTION) + 3 );
775
+ if (command == NULL ) return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
776
+ sprintf (command, " %s=?" , LTE_SHIELD_OPERATOR_SELECTION);
777
+
778
+ response = lte_calloc_char (maxOps*48 + 16 );
779
+ if (response == NULL )
780
+ {
781
+ free (command);
782
+ return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
783
+ }
784
+
785
+ // AT+COPS maximum response time is 3 minutes (180000 ms)
786
+ err = sendCommandWithResponse (command, LTE_SHIELD_RESPONSE_OK, response,
787
+ 180000 );
788
+
789
+ // Sample responses:
790
+ // +COPS: (3,"Verizon Wireless","VzW","311480",8),,(0,1,2,3,4),(0,1,2)
791
+ // +COPS: (1,"313 100","313 100","313100",8),(2,"AT&T","AT&T","310410",8),(3,"311 480","311 480","311480",8),,(0,1,2,3,4),(0,1,2)
792
+
793
+ if (err == LTE_SHIELD_ERROR_SUCCESS)
794
+ {
795
+ char * opBegin;
796
+ char * opEnd;
797
+ int op = 0 ;
798
+ int sscanRead = 0 ;
799
+ int stat;
800
+ char longOp[26 ];
801
+ char shortOp[11 ];
802
+ uint8_t act;
803
+ unsigned long numOp;
804
+
805
+ opBegin = response;
806
+
807
+ for (; op < maxOps; op++)
808
+ {
809
+ opBegin = strchr (opBegin, ' (' );
810
+ if (opBegin == NULL ) break ;
811
+ opEnd = strchr (opBegin, ' )' );
812
+ if (opEnd == NULL ) break ;
813
+
814
+ int sscanRead = sscanf (opBegin, " (%d,\" %[^\" ]\" ,\" %[^\" ]\" ,\" %lu\" ,%d)%*s" ,
815
+ &stat, longOp, shortOp, &numOp, &act);
816
+ if (sscanRead == 5 )
817
+ {
818
+ opRet[op].stat = stat;
819
+ opRet[op].longOp = (String)(longOp);
820
+ opRet[op].shortOp = (String)(shortOp);
821
+ opRet[op].numOp = numOp;
822
+ opRet[op].act = act;
823
+ opsSeen += 1 ;
824
+ }
825
+ // TODO: Search for other possible patterns here
826
+ else
827
+ {
828
+ break ; // Break out if pattern doesn't match.
829
+ }
830
+ opBegin = opEnd + 1 ; // Move opBegin to beginning of next value
831
+ }
832
+ }
833
+
834
+ free (command);
835
+ free (response);
836
+
837
+ return opsSeen;
838
+ }
839
+
840
+ LTE_Shield_error_t LTE_Shield::registerOperator (struct operator_stats oper)
841
+ {
842
+ LTE_Shield_error_t err;
843
+ char * command;
844
+
845
+ command = lte_calloc_char (strlen (LTE_SHIELD_OPERATOR_SELECTION) + 24 );
846
+ if (command == NULL ) return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
847
+ sprintf (command, " %s=1,2,\" %lu\" " , LTE_SHIELD_OPERATOR_SELECTION, oper.numOp );
848
+
849
+ // AT+COPS maximum response time is 3 minutes (180000 ms)
850
+ err = sendCommandWithResponse (command, LTE_SHIELD_RESPONSE_OK, NULL ,
851
+ 180000 );
655
852
656
853
return err;
657
854
}
658
855
856
+ LTE_Shield_error_t LTE_Shield::getOperator (String * oper)
857
+ {
858
+ LTE_Shield_error_t err;
859
+ char * command;
860
+ char * response;
861
+ char * searchPtr;
862
+ char mode;
863
+
864
+ command = lte_calloc_char (strlen (LTE_SHIELD_OPERATOR_SELECTION) + 3 );
865
+ if (command == NULL ) return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
866
+ sprintf (command, " %s?" , LTE_SHIELD_OPERATOR_SELECTION);
867
+
868
+ response = lte_calloc_char (64 );
869
+ if (response == NULL )
870
+ {
871
+ free (command);
872
+ return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
873
+ }
874
+
875
+ // AT+COPS maximum response time is 3 minutes (180000 ms)
876
+ err = sendCommandWithResponse (command, LTE_SHIELD_RESPONSE_OK, response,
877
+ 180000 );
878
+
879
+ if (err == LTE_SHIELD_ERROR_SUCCESS)
880
+ {
881
+ searchPtr = strstr (response, " +COPS: " );
882
+ if (searchPtr != NULL )
883
+ {
884
+ searchPtr += strlen (" +COPS: " ); // Move searchPtr to first char
885
+ mode = *searchPtr; // Read first char -- should be mode
886
+ if (mode == ' 2' ) // Check for de-register
887
+ {
888
+ err = LTE_SHIELD_ERROR_DEREGISTERED;
889
+ }
890
+ // Otherwise if it's default, manual, set-only, or automatic
891
+ else if ((mode == ' 0' ) || (mode == ' 1' ) || (mode == ' 3' ) || (mode == ' 4' ))
892
+ {
893
+ *oper = " " ;
894
+ searchPtr = strchr (searchPtr, ' \" ' ); // Move to first quote
895
+ if (searchPtr == NULL )
896
+ {
897
+ err = LTE_SHIELD_ERROR_DEREGISTERED;
898
+ }
899
+ else
900
+ {
901
+ while ((*(++searchPtr) != ' \" ' ) && (searchPtr != ' \0 ' ))
902
+ {
903
+ oper->concat (*(searchPtr));
904
+ }
905
+ }
906
+ // Serial.println("Operator: " + *oper);
907
+ // oper->concat('\0');
908
+ }
909
+ }
910
+ }
911
+
912
+ free (response);
913
+ free (command);
914
+ return err;
915
+ }
916
+
917
+ LTE_Shield_error_t LTE_Shield::deregisterOperator (void )
918
+ {
919
+ LTE_Shield_error_t err;
920
+ char * command;
921
+
922
+ command = lte_calloc_char (strlen (LTE_SHIELD_OPERATOR_SELECTION) + 4 );
923
+ if (command == NULL ) return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
924
+ sprintf (command, " %s=2" , LTE_SHIELD_OPERATOR_SELECTION);
925
+
926
+ err = sendCommandWithResponse (command, LTE_SHIELD_RESPONSE_OK, NULL ,
927
+ LTE_SHIELD_STANDARD_RESPONSE_TIMEOUT);
928
+
929
+ return err;
930
+ }
659
931
660
932
LTE_Shield_error_t LTE_Shield::setSMSMessageFormat (lte_shield_message_format_t textMode)
661
933
{
@@ -1230,6 +1502,8 @@ LTE_Shield_error_t LTE_Shield::getMno(mobile_network_operator_t * mno)
1230
1502
LTE_Shield_error_t err;
1231
1503
char * command;
1232
1504
char * response;
1505
+ const char * mno_keys = " 0123456" ; // Valid MNO responses
1506
+ int i;
1233
1507
1234
1508
command = lte_calloc_char (strlen (LTE_SHIELD_COMMAND_MNO) + 2 );
1235
1509
if (command == NULL ) return LTE_SHIELD_ERROR_OUT_OF_MEMORY;
@@ -1240,11 +1514,8 @@ LTE_Shield_error_t LTE_Shield::getMno(mobile_network_operator_t * mno)
1240
1514
1241
1515
err = sendCommandWithResponse (command, LTE_SHIELD_RESPONSE_OK,
1242
1516
response, LTE_SHIELD_STANDARD_RESPONSE_TIMEOUT);
1243
-
1244
1517
if (err != LTE_SHIELD_ERROR_SUCCESS) return err;
1245
1518
1246
- const char * mno_keys = " 0123456" ; // Valid MNO responses
1247
- int i;
1248
1519
i = strcspn (response, mno_keys); // Find first occurence of MNO key
1249
1520
if (i == strlen (response))
1250
1521
{
@@ -1321,7 +1592,7 @@ LTE_Shield_error_t LTE_Shield::waitForResponse(char * expectedResponse, uint16_t
1321
1592
1322
1593
LTE_Shield_error_t LTE_Shield::sendCommandWithResponse (
1323
1594
const char * command, char * expectedResponse, char * responseDest,
1324
- uint16_t commandTimeout, boolean at)
1595
+ unsigned long commandTimeout, boolean at)
1325
1596
{
1326
1597
unsigned long timeIn;
1327
1598
boolean found = false ;
0 commit comments