]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/net/cellular/CellularModem/link/LinkMonitor.cpp
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / net / cellular / CellularModem / link / LinkMonitor.cpp
1 /* LinkMonitor.cpp */
2 /* Copyright (C) 2012 mbed.org, MIT License
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
5  * and associated documentation files (the "Software"), to deal in the Software without restriction,
6  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
7  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in all copies or
11  * substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
14  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18  */
19
20 #define __DEBUG__ 0
21 #ifndef __MODULE__
22 #define __MODULE__ "LinkMonitor.cpp"
23 #endif
24
25 #include "core/fwk.h"
26
27 #include "LinkMonitor.h"
28
29 #include <cstdio>
30 using std::sscanf;
31
32 #define DEFAULT_TIMEOUT 10000
33
34 LinkMonitor::LinkMonitor(ATCommandsInterface* pIf) : m_pIf(pIf), m_rssi(0), m_registrationState(REGISTRATION_STATE_UNKNOWN), m_bearer(BEARER_UNKNOWN)
35 {
36   m_gsm = true;
37 }
38
39 int LinkMonitor::init(bool gsm)
40 {
41   m_gsm = gsm;
42   if (m_gsm)
43   {
44     // we need to make sure that we setup the operator selection to be in 'numeric' format.
45     // i.e. it is made up of a network and country code when returned by the modem e.g. Operator = 23415. This allows easy logic parsing for
46     // setting up other network parameters in future.
47     DBG("LinkMonitor::init() being called. This should only happen once: executinging AT+COPS=0,2");  
48     int ret = m_pIf->executeSimple("AT+COPS=0,2", NULL, DEFAULT_TIMEOUT); //Configure to set the operator string to Country Code and mobile network code
49     if(ret != OK)
50     {
51       WARN(" NET_PROTOCOL error from sending the AT+COPS command to the modem. ");
52       return NET_PROTOCOL;
53     }
54   }
55   return OK;
56 }
57
58 /*virtual*/ int LinkMonitor::onNewATResponseLine(ATCommandsInterface* pInst, const char* line)
59 {
60   DBG("Line is %s", line);
61   char n[32] = "";
62   char s[32] = "";
63   int v;
64   if( sscanf(line, "+CREG: %*d,%d", &v) >= 1 ) //Reg state is valid
65   {
66     DBG("+CREG %d", v);
67     switch( v )
68     {
69       case 0:
70         m_registrationState = REGISTRATION_STATE_UNKNOWN;
71         break;
72       case 1:
73         m_registrationState = REGISTRATION_STATE_HOME_NETWORK;
74         break;
75       case 2:
76         m_registrationState = REGISTRATION_STATE_REGISTERING;
77         break;
78       case 3:
79         m_registrationState = REGISTRATION_STATE_DENIED;  
80         break;
81       case 4:
82         m_registrationState = REGISTRATION_STATE_NO_SIGNAL;  
83         break;        
84       case 5:
85         m_registrationState = REGISTRATION_STATE_ROAMING;  
86         break;
87       default:
88         m_registrationState = REGISTRATION_STATE_UNKNOWN;  
89         break;
90     }
91   }
92   else if( sscanf(line, "+COPS: %*d,%*d,\"%*[^\"]\",%d", &v) >= 1 )
93   {
94     DBG("+COPS %d", v);
95     switch( v )
96     {
97       case 0:
98         m_bearer = BEARER_GSM;
99         break;
100       case 2:
101         m_bearer = BEARER_UMTS;
102         break;
103       case 3:
104         m_bearer = BEARER_EDGE;
105         break;
106       case 4: //HSDPA
107       case 5: //HSUPA
108       case 6: //HSDPA + HSUPA
109         m_bearer = BEARER_HSPA;
110         break;
111       case 7:
112         m_bearer = BEARER_LTE;
113         break;  
114       case 1: //GSM Compact
115       default:
116         m_bearer = BEARER_UNKNOWN;
117         break;
118     }
119   }
120   else if( sscanf(line, "+CSQ: %d,%*d", &v) >= 1 )
121   {
122     DBG("+CSQ %d", v);
123     if(v == 99) //Unknown
124     {
125       m_rssi = 0; //Unknown
126     }
127     else
128     {
129       m_rssi = -113 + 2*v;
130     }
131   }
132   else if ( (sscanf(line, "+CNUM: \"%[^\"]\",\"%[^\"]\",%d", n, s, &v) == 3) || 
133             (sscanf(line, "+CNUM: \"\",\"%[^\"]\",%d", s, &v) == 2) )
134   {
135       if (*s && ((v == 145/*number includes + */) || (v == 129/*otherwise*/))) {
136         strcpy(m_phoneNumber, s);
137       }
138   }
139   return OK;
140 }
141
142 /*virtual*/ int LinkMonitor::onNewEntryPrompt(ATCommandsInterface* pInst)
143 {
144   return OK;
145 }
146
147 int LinkMonitor::getState(int* pRssi, REGISTRATION_STATE* pRegistrationState, BEARER* pBearer)
148 {
149   m_rssi = 0;
150   m_registrationState = REGISTRATION_STATE_UNKNOWN;
151   m_bearer = BEARER_UNKNOWN;
152   int ret = m_pIf->execute(m_gsm ? "AT+CREG?;+COPS?;+CSQ" : "AT+CREG?;+CSQ", this, NULL, DEFAULT_TIMEOUT); //Configure to get registration info & get it; get signal quality
153   if(ret != OK)
154   {
155     return NET_PROTOCOL;
156   }
157   *pRssi = m_rssi;
158   *pRegistrationState = m_registrationState;
159   *pBearer = m_bearer;
160   return OK;
161 }
162
163 int LinkMonitor::getPhoneNumber(char* phoneNumber)
164 {
165   *m_phoneNumber = '\0';
166   if (m_gsm) {
167     int ret = m_pIf->execute("AT+CNUM", this, NULL, DEFAULT_TIMEOUT);
168     if(ret != OK)
169     {
170       return NET_PROTOCOL;
171     }
172   }
173   strcpy(phoneNumber, m_phoneNumber);
174   return OK;
175 }