RDK Documentation (Open Sourced RDK Components)
btrMgr_LEOnboarding.c
Go to the documentation of this file.
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2016 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 /**
20  * @file btrMgr_LeOnboarding.c
21  *
22  * @description This file implements bluetooth manager's
23  *
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 
30 /* System Headers */
31 #include <stdlib.h>
32 #include <stdbool.h>
33 #include <string.h>
34 #include <stdio.h>
35 
36 /* Ext lib Headers */
37 
38 #ifdef BTRTEST_LE_ONBRDG_ENABLE
39 #include "libIBus.h"
40 #include "libIARM.h"
41 
42 #include "wifiSrvMgrIarmIf.h"
43 
44 #include "sysMgr.h"
45 #endif
46 
47 
48 #include "cJSON.h"
49 //#include "sysUtils.h"
50 
51 
52 #include "ecdh.h"
53 #include "btrMgr_Types.h"
54 #include "btrMgr_logger.h"
55 #include "btrMgr_LEOnboarding.h"
56 
57 #define get_value_string(obj,str) strcpy(str, obj->valuestring);
58 
59 
60 #define get_value_number(obj, num) num = obj->valueint;
61 
62 #define kPrivateKeyPath "/tmp/bootstrap_private.pem"
63 #define kPublicKeyPath "/tmp/bootstrap_public.pem"
64 
65 /* router security mode */
66 enum SECURITY_MODE
67 {
68  SECURITY_MODE_NONE = 1, /* none */
69  SECURITY_MODE_WPA2_PSK, /* WPA2-PSK (AES) */
70  SECURITY_MODE_RESERVED1,
71  SECURITY_MODE_WPA_WPA2_PSK /* WPAWPA2 PSK (TKIP/AES) */
72 };
73 
74 
75 int gLeOnboardingState = BTRMGR_LE_ONBRDG_UNDEFINED;
76 short int gUuidProvisionStatus = 0;
77 char gWifiPayload[MAX_PAYLOAD_LEN];
78 int gWifiPayloadLen = 0;
79 int gDataLenRxd = 0;
80 bool gWifiPayloadDecodeSuccess = false;
81 bool gWifiConnectSuccess = false;
82 bool gWifiPayloadRxd = false;
83 typedef struct wifi_credentials wifi_creds_t;
84 wifi_creds_t WifiCreds;
85 
86 eBTRMgrRet BTRMGR_LeWifi_CheckWifiConnSuccess(char* aSSID);
87 static void BTRMGR_LeLoadDatatoBuffer(char *aData);
88 static int get_wifi_creds(cJSON* wifi_settings, wifi_creds_t *creds, int index, int *ptotalEntries);
89 void BTRMGR_LeDecodeRxdWifiPayload(char * agWifiPayload);
90 eBTRMgrRet BTRMGR_LeWifi_ConnectToWifi(char* aSSID, char* aPassword, int aSecurityMode);
91 
92 //Function to get publickey
93 static void
94 get_publicKey (
95  char* key
96 ) {
97  FILE *file = NULL;
98  int nread;
99  char header[] = "-----BEGIN PUBLIC KEY-----";
100  char footer[] = "-----END PUBLIC KEY-----";
101  size_t len = 0;
102  char *line = NULL;
103 
104  file = fopen(kPublicKeyPath, "r");
105  if (file) {
106  while ((nread = getline(&line, &len, file)) != -1) {
107  if ((strncmp(line, header, nread - 1) != 0) && (strncmp(line, footer, nread - 1) != 0)) {
108  strncpy(&key[strlen(key)], line, nread - 1);
109  }
110  }
111 
112  free(line);
113  fclose(file);
114  }
115 }
116 
117 static void
118 BTRMGR_LeLoadDatatoBuffer (
119  char* aData
120 ) {
121  if (gWifiPayloadLen == 0) {
122  sscanf(aData, "%4x", &gWifiPayloadLen);
123  BTRMGRLOG_DEBUG("Data length is %d", gWifiPayloadLen);
124  aData += 4;
125  }
126  gDataLenRxd += snprintf(&gWifiPayload[gDataLenRxd], 2048, "%s", aData);
127 
128  BTRMGRLOG_DEBUG("\nLength received is %d\n", gDataLenRxd);
129 
130  if (gDataLenRxd == gWifiPayloadLen) {
131  BTRMGRLOG_DEBUG("Data is %s", gWifiPayload);
132  }
133 }
134 
135 
136 //Function to parse cjson wifi credentials string
137 static int
138 get_wifi_creds (
139  cJSON* wifi_settings,
140  wifi_creds_t* creds,
141  int index,
142  int* ptotalEntries
143 ) {
144  int noofEntries = 0;
145  int ret = -1;
146  //PRVMGR_ASSERT_NOT_NULL(wifi_settings);
147 
148  noofEntries = cJSON_GetArraySize(wifi_settings);
149  *ptotalEntries = noofEntries;
150  BTRMGRLOG_DEBUG("noofEntries in ssid json %d and current index %d", *ptotalEntries, index);
151 
152  if (noofEntries >= index) {
153  cJSON* cur_ssid = cJSON_GetArrayItem(wifi_settings, (index - 1));
154  //PRVMGR_ASSERT_NOT_NULL(cur_ssid);
155 
156  get_value_string(cJSON_GetObjectItem(cur_ssid, "ssid"), creds->ssid);
157  BTRMGRLOG_INFO("creds->ssid (%s)", creds->ssid);
158 
159  get_value_string(cJSON_GetObjectItem(cur_ssid, "password"), creds->passphrase);
160  BTRMGRLOG_DEBUG("creds->passphrase (%s)", creds->passphrase);
161 
162  if (!cJSON_GetObjectItem(cur_ssid, "frequency")) {
163  BTRMGRLOG_WARN("json doesn't have frequency... using default");
164  }
165  else {
166  get_value_string(cJSON_GetObjectItem(cur_ssid, "frequency"), creds->frequency);
167  }
168  BTRMGRLOG_INFO("creds->frequency (%s)", creds->frequency);
169 
170  if (!cJSON_GetObjectItem(cur_ssid, "securitymode")) {
171  BTRMGRLOG_WARN("json doesn't have securitymode... using default");
172  creds->securitymode = SECURITY_MODE_WPA_WPA2_PSK;
173  }
174  else {
175  get_value_number(cJSON_GetObjectItem(cur_ssid, "securitymode"), creds->securitymode);
176  }
177  BTRMGRLOG_INFO("creds->securitymode (%d)", creds->securitymode);
178  ret = 0;
179  }
180  else {
181  BTRMGRLOG_ERROR("Error index %d greater than available entries %d", index, noofEntries);
182  ret = -1;
183  }
184 
185  return ret;
186 }
187 
188 void
189 BTRMGR_LeDecodeRxdWifiPayload (
190  char* agWifiPayload
191 ) {
192  cJSON* psrv_payload = NULL;
193  cJSON* wifi_settings = NULL;
194  int noofEntries;
195  int entry = 1;
196 
197  psrv_payload = cJSON_Parse((char const*)agWifiPayload);
198  if (!psrv_payload) {
199  BTRMGRLOG_DEBUG("wifi_payload parse error!!");
200  }
201  else {
202  //decrypt wifi settings
203 
204  BTRMGRLOG_DEBUG("decrypt wifi settings");
205  int sts = ECDH_DecryptWiFiSettings(psrv_payload, &wifi_settings);
206  if (sts != 1) {
207  BTRMGRLOG_ERROR("Unable to decrypt wifi settings");
208  }
209  else {
210  memset(&WifiCreds, 0, sizeof(WifiCreds));
211  int ret = get_wifi_creds(wifi_settings, &WifiCreds, entry, &noofEntries);
212  if (ret == 0) {
213  BTRMGRLOG_DEBUG("wifi creds for %s radio: ssid (%s) password (%s)",
214  WifiCreds.frequency, WifiCreds.ssid, WifiCreds.passphrase);
215  gWifiPayloadDecodeSuccess = true;
216  }
217  }
218  }
219 }
220 
221 /* Interfaces */
223 BTRMGR_LeOnboarding_GetData (
224  BTRMGR_LeOnboardingChar_t aenLeOnboardingChar,
225  char* aData
226 ) {
227  eBTRMgrRet rc = eBTRMgrSuccess;
228  //IARM_Result_t lIARMStatus = IARM_RESULT_SUCCESS;
229 
230  switch (aenLeOnboardingChar) {
231  case BTRMGR_LE_ONBRDG_SYSTEMID: {
232  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "%s", "3C9872F8DA9F");
233  }
234  break;
235  case BTRMGR_LE_ONBRDG_HWREVISION:
236  case BTRMGR_LE_ONBRDG_MODELNUMBER: {
237  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "%s", "SCHC2AEW");
238  }
239  break;
240  case BTRMGR_LE_ONBRDG_SERIALNUMBER: {
241  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "%s", "S1807CKZ000113");
242  }
243  break;
244  case BTRMGR_LE_ONBRDG_FWREVISION: {
245  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "%s", "V.0.0.1");
246  }
247  break;
248  case BTRMGR_LE_ONBRDG_SWREVISION: {
249  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "%s", "SCHC2_0917_VBN");
250  }
251  break;
252  case BTRMGR_LE_ONBRDG_MFGRNAME: {
253  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "%s", "Sercomm");
254  }
255  break;
256  case BTRMGR_LE_ONBRDG_UUID_QR_CODE: {
257  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "%s", "SCHC2AEW.S1807CKZ000113.3C9872F8DA9F");
258  }
259  break;
260  case BTRMGR_LE_ONBRDG_UUID_PROVISION_STATUS: {
261  switch (gLeOnboardingState) {
262  case BTRMGR_LE_ONBRDG_UNDEFINED: {
263  gWifiPayloadDecodeSuccess = false;
264  gLeOnboardingState = BTRMGR_LE_ONBRDG_ADVERTISE;
265  }
266  break;
267  case BTRMGR_LE_ONBRDG_ADVERTISE: {
268  gLeOnboardingState = BTRMGR_LE_ONBRDG_BT_PAIRING;
269  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "0x%x", 0);
270  }
271  break;
272  case BTRMGR_LE_ONBRDG_BT_PAIRING: {
273  gLeOnboardingState = BTRMGR_LE_ONBRDG_INPROGRESS;
274  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "0x%x", BTRMGR_LE_ONBRDG_AWAITING_WIFI_CONFIG);
275  }
276  break;
277  case BTRMGR_LE_ONBRDG_INPROGRESS: {
278  gLeOnboardingState = BTRMGR_LE_ONBRDG_GET_WIFI_CREDS;
279  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "0x%x", BTRMGR_LE_ONBRDG_AWAITING_WIFI_CONFIG);
280  }
281  break;
282  case BTRMGR_LE_ONBRDG_GET_WIFI_CREDS: {
283  if(true == gWifiPayloadRxd) {
284  gLeOnboardingState = BTRMGR_LE_ONBRDG_CONNECT_WIFI;
285  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "0x%x", BTRMGR_LE_ONBRDG_PROCESSING_WIFI_CONFIG);
286  }
287  else {
288  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "0x%x", BTRMGR_LE_ONBRDG_AWAITING_WIFI_CONFIG);
289  }
290  }
291  break;
292  case BTRMGR_LE_ONBRDG_CONNECT_WIFI: {
293  if ((true == gWifiConnectSuccess) && (eBTRMgrSuccess == BTRMGR_LeWifi_CheckWifiConnSuccess(WifiCreds.ssid))) {
294  BTRMGRLOG_INFO("Wifi is connected\n");
295  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "0x%x", BTRMGR_LE_ONBRDG_WIFI_CONNECT_SUCCESS);
296  gLeOnboardingState = BTRMGR_LE_ONBRDG_COMPLETE;
297  }
298  else if (true == gWifiPayloadDecodeSuccess) {
299  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "0x%x", BTRMGR_LE_ONBRDG_CONNECTING_TO_WIFI);
300  WifiCreds.securitymode = 6;
301  if (eBTRMgrSuccess == BTRMGR_LeWifi_ConnectToWifi(WifiCreds.ssid, WifiCreds.passphrase, WifiCreds.securitymode)) {
302  gWifiConnectSuccess = true;
303  }
304  }
305  }
306  break;
307  case BTRMGR_LE_ONBRDG_COMPLETE: {
308  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "0x%x", BTRMGR_LE_ONBRDG_COMPLETE_SUCCESS);
309  }
310  break;
311  default:
312  break;
313  }
314 
315  BTRMGRLOG_INFO("Onboarding status is %d\n", gLeOnboardingState);
316  }
317  break;
318  case BTRMGR_LE_ONBRDG_UUID_PUBLIC_KEY: {
319  char lPublicKey[MAX_LEN_PUBLIC_KEY] = "";
320  get_publicKey(lPublicKey);
321  int ret =snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "%s", lPublicKey);
322  if (ret > (BTRMGR_LE_STR_LEN_MAX - 1)) {
323  BTRMGRLOG_DEBUG("BTRMGR_LE_ONBRDG_UUID_PUBLIC_KEY truncated\n");
324  }
325 
326  }
327  break;
328  case BTRMGR_LE_ONBRDG_UUID_WIFI_CONFIG: {
329  }
330  break;
331  case BTRMGR_LE_ONBRDG_UUID_SSID_LIST: {
332  snprintf(aData, (BTRMGR_LE_STR_LEN_MAX - 1), "%s", " ");
333  }
334  break;
335  default:
336  rc = eBTRMgrFailure;
337  break;
338  }
339 
340  return rc;
341 }
342 
344 BTRMGR_LeOnboarding_SetData (
345  BTRMGR_LeOnboardingChar_t aenLeOnboardingChar,
346  char* payload
347 ) {
348  eBTRMgrRet rc = eBTRMgrSuccess;
349 
350  switch(aenLeOnboardingChar) {
351  case BTRMGR_LE_ONBRDG_UUID_WIFI_CONFIG: {
352  char tempBuffer[BTRMGR_LE_STR_LEN_MAX] = "\0";
353  int datatxd = 0;
354  char *ptrPayload = payload;
355  int index = 0;
356  BTRMGRLOG_DEBUG("Length of payload is %u\n", (unsigned int)strlen(payload));
357  BTRMGRLOG_INFO("Payload is %s\n", payload);
358  for (index = 0; index < strlen(payload);) {
359  datatxd = snprintf(tempBuffer, BTRMGR_LE_STR_LEN_MAX, "%s", ptrPayload);
360  BTRMGRLOG_DEBUG("data txd is %d\n", datatxd);
361  if (datatxd > 0) {
362  if (datatxd > BTRMGR_LE_STR_LEN_MAX) {
363  tempBuffer[BTRMGR_LE_STR_LEN_MAX-1] = '\0';
364  BTRMGRLOG_DEBUG("Tx buffer is %s\n", tempBuffer);
365  BTRMGR_LeLoadDatatoBuffer(tempBuffer);
366  index += strlen(tempBuffer);
367  ptrPayload = &payload[index];
368  }
369  else {
370  BTRMGR_LeLoadDatatoBuffer(tempBuffer);
371  index += datatxd;
372  }
373  BTRMGRLOG_DEBUG("index is %d\n", index);
374  }
375  }
376 
377  if (gDataLenRxd == gWifiPayloadLen) {
378  gWifiPayloadRxd = true;
379  BTRMGRLOG_DEBUG("Data is %s", gWifiPayload);
380  gWifiPayloadLen = 0;
381  /* Decode received data */
382  BTRMGR_LeDecodeRxdWifiPayload(gWifiPayload);
383  }
384  }
385  break;
386  default:
387  break;
388  }
389 
390  return rc;
391 }
392 
394 BTRMGR_LeWifi_CheckWifiConnSuccess (
395  char* aSSID
396 ) {
397  eBTRMgrRet lRetCode = eBTRMgrFailure;
398 
399 #ifdef BTRTEST_LE_ONBRDG_ENABLE
400  //IARM_Result_t retVal = IARM_RESULT_SUCCESS;
402 
403  memset(&param, 0, sizeof(param));
404 
405  IARM_Bus_Call(IARM_BUS_NM_SRV_MGR_NAME, IARM_BUS_WIFI_MGR_API_getConnectedSSID, (void *)&param, sizeof(param));
406 
407  if (!strncmp(param.data.getConnectedSSID.ssid, aSSID, strlen(aSSID))) {
408  BTRMGRLOG_DEBUG("Wifi has been successfully connected\n");
409  lRetCode = eBTRMgrSuccess;
410  }
411 #else
412  BTRMGRLOG_DEBUG("Wifi not available\n");
413 #endif /* #ifdef BTRTEST_LE_ONBRDG_ENABLE */
414 
415  return lRetCode;
416 }
417 
419 BTRMGR_LeWifi_ConnectToWifi (
420  char* aSSID,
421  char* aPassword,
422  int aSecurityMode
423 ) {
424  eBTRMgrRet lRetCode = eBTRMgrSuccess;
425 
426 #ifdef BTRTEST_LE_ONBRDG_ENABLE
427  IARM_Result_t retVal = IARM_RESULT_SUCCESS;
429 
430  strcpy(param.data.connect.ssid, aSSID);
431  strcpy(param.data.connect.passphrase, aPassword);
432  param.data.connect.security_mode = (SsidSecurity)aSecurityMode;
433  BTRMGRLOG_DEBUG("Wifi ssid is : %s\n", aSSID);
434  BTRMGRLOG_DEBUG("Wifi pwd is : %s\n", aPassword);
435  BTRMGRLOG_DEBUG("Wifi sec mode is : %d\n", param.data.connect.security_mode);
436  retVal = IARM_Bus_Call(IARM_BUS_NM_SRV_MGR_NAME, IARM_BUS_WIFI_MGR_API_connect, (void *)&param, sizeof(param));
437 
438  BTRMGRLOG_DEBUG("\"%s\", status: \"%s\"", IARM_BUS_WIFI_MGR_API_connect, ((retVal == IARM_RESULT_SUCCESS && param.status) ? "Success" : "Failure"));
439  if (retVal != IARM_RESULT_SUCCESS) {
440  lRetCode = eBTRMgrFailure;
441  }
442 #else
443  BTRMGRLOG_DEBUG("Wifi not available\n");
444 #endif /* #ifdef BTRTEST_LE_ONBRDG_ENABLE */
445 
446  return lRetCode;
447 }
448 
btrMgr_Types.h
sysMgr.h
IARM-Bus Sys Manager Public API.
IARM_Bus_Call
IARM_Result_t IARM_Bus_Call(const char *ownerName, const char *methodName, void *arg, size_t argLen)
This API is used to Invoke RPC method by its application name and method name.
Definition: iarm_bus.c:57
IARM_BUS_WIFI_MGR_API_connect
#define IARM_BUS_WIFI_MGR_API_connect
Definition: wifiSrvMgrIarmIf.h:65
SsidSecurity
enum _SsidSecurity SsidSecurity
libIBus.h
RDK IARM-Bus API Declarations.
eBTRMgrRet
enum _eBTRMgrRet eBTRMgrRet
Represents the bluetooth manager return values.
IARM_BUS_WIFI_MGR_API_getConnectedSSID
#define IARM_BUS_WIFI_MGR_API_getConnectedSSID
Definition: wifiSrvMgrIarmIf.h:61
wifi_credentials
Definition: btrMgr_LEOnboarding.h:83
_IARM_Bus_WiFiSrvMgr_Param_t
Definition: wifiSrvMgrIarmIf.h:258
btrMgr_LEOnboarding.h