Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

1483 linhas
44 KiB

  1. /**
  2. *
  3. * \file
  4. *
  5. * \brief This module contains M2M Wi-Fi APIs implementation.
  6. *
  7. * Copyright (c) 2017-2018 Microchip Technology Inc. and its subsidiaries.
  8. *
  9. * \asf_license_start
  10. *
  11. * \page License
  12. *
  13. * Subject to your compliance with these terms, you may use Microchip
  14. * software and any derivatives exclusively with Microchip products.
  15. * It is your responsibility to comply with third party license terms applicable
  16. * to your use of third party software (including open source software) that
  17. * may accompany Microchip software.
  18. *
  19. * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
  20. * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
  21. * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
  22. * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
  23. * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
  24. * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
  25. * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
  26. * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
  27. * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
  28. * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
  29. * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
  30. *
  31. * \asf_license_stop
  32. *
  33. */
  34. #include "driver/include/m2m_wifi.h"
  35. #include "driver/source/m2m_hif.h"
  36. #include "driver/source/nmasic.h"
  37. #include <stdlib.h>
  38. static volatile uint8 gu8ChNum;
  39. static tpfAppWifiCb gpfAppWifiCb = NULL;
  40. #ifdef ETH_MODE
  41. static tpfAppEthCb gpfAppEthCb = NULL;
  42. static uint8* gau8ethRcvBuf=NULL;
  43. static uint16 gu16ethRcvBufSize ;
  44. #endif
  45. //#define CONF_MGMT
  46. #ifdef CONF_MGMT
  47. static tpfAppMonCb gpfAppMonCb = NULL;
  48. static struct _tstrMgmtCtrl
  49. {
  50. uint8* pu8Buf;
  51. uint16 u16Offset;
  52. uint16 u16Sz;
  53. }
  54. gstrMgmtCtrl = {NULL, 0 , 0};
  55. #endif
  56. /**
  57. * @fn m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr, uint8 grp)
  58. * @brief WiFi call back function
  59. * @param [in] u8OpCode
  60. * HIF Opcode type.
  61. * @param [in] u16DataSize
  62. * HIF data length.
  63. * @param [in] u32Addr
  64. * HIF address.
  65. * @param [in] grp
  66. * HIF group type.
  67. * @author
  68. * @date
  69. * @version 1.0
  70. */
  71. static void m2m_wifi_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
  72. {
  73. uint8 rx_buf[8];
  74. if (u8OpCode == M2M_WIFI_RESP_CON_STATE_CHANGED)
  75. {
  76. tstrM2mWifiStateChanged strState;
  77. if (hif_receive(u32Addr, (uint8*) &strState,sizeof(tstrM2mWifiStateChanged), 0) == M2M_SUCCESS)
  78. {
  79. if (gpfAppWifiCb)
  80. gpfAppWifiCb(M2M_WIFI_RESP_CON_STATE_CHANGED, &strState);
  81. }
  82. }
  83. else if (u8OpCode == M2M_WIFI_RESP_GET_SYS_TIME)
  84. {
  85. tstrSystemTime strSysTime;
  86. if (hif_receive(u32Addr, (uint8*) &strSysTime,sizeof(tstrSystemTime), 0) == M2M_SUCCESS)
  87. {
  88. if (gpfAppWifiCb)
  89. gpfAppWifiCb(M2M_WIFI_RESP_GET_SYS_TIME, &strSysTime);
  90. }
  91. }
  92. else if(u8OpCode == M2M_WIFI_RESP_CONN_INFO)
  93. {
  94. tstrM2MConnInfo strConnInfo;
  95. if(hif_receive(u32Addr, (uint8*)&strConnInfo, sizeof(tstrM2MConnInfo), 1) == M2M_SUCCESS)
  96. {
  97. if(gpfAppWifiCb)
  98. gpfAppWifiCb(M2M_WIFI_RESP_CONN_INFO, &strConnInfo);
  99. }
  100. }
  101. else if (u8OpCode == M2M_WIFI_RESP_MEMORY_RECOVER)
  102. {
  103. #if 0
  104. if (hif_receive(u32Addr, rx_buf, 4, 1) == M2M_SUCCESS)
  105. {
  106. tstrM2mWifiStateChanged strState;
  107. m2m_memcpy((uint8*) &strState, rx_buf,sizeof(tstrM2mWifiStateChanged));
  108. if (app_wifi_recover_cb)
  109. app_wifi_recover_cb(strState.u8CurrState);
  110. }
  111. #endif
  112. }
  113. else if (u8OpCode == M2M_WIFI_REQ_DHCP_CONF)
  114. {
  115. tstrM2MIPConfig strIpConfig;
  116. if (hif_receive(u32Addr, (uint8 *)&strIpConfig, sizeof(tstrM2MIPConfig), 0) == M2M_SUCCESS)
  117. {
  118. if (gpfAppWifiCb)
  119. gpfAppWifiCb(M2M_WIFI_REQ_DHCP_CONF, (uint8 *)&strIpConfig);
  120. }
  121. }
  122. else if (u8OpCode == M2M_WIFI_REQ_WPS)
  123. {
  124. tstrM2MWPSInfo strWps;
  125. m2m_memset((uint8*)&strWps,0,sizeof(tstrM2MWPSInfo));
  126. if(hif_receive(u32Addr, (uint8*)&strWps, sizeof(tstrM2MWPSInfo), 0) == M2M_SUCCESS)
  127. {
  128. if (gpfAppWifiCb)
  129. gpfAppWifiCb(M2M_WIFI_REQ_WPS, &strWps);
  130. }
  131. }
  132. else if (u8OpCode == M2M_WIFI_RESP_IP_CONFLICT)
  133. {
  134. uint32 u32ConflictedIP;
  135. if(hif_receive(u32Addr, (uint8 *)&u32ConflictedIP, sizeof(u32ConflictedIP), 0) == M2M_SUCCESS)
  136. {
  137. M2M_INFO("Conflicted IP \" %u.%u.%u.%u \" \n",
  138. BYTE_0(u32ConflictedIP),BYTE_1(u32ConflictedIP),BYTE_2(u32ConflictedIP),BYTE_3(u32ConflictedIP));
  139. if (gpfAppWifiCb)
  140. gpfAppWifiCb(M2M_WIFI_RESP_IP_CONFLICT, NULL);
  141. }
  142. }
  143. else if (u8OpCode == M2M_WIFI_RESP_SCAN_DONE)
  144. {
  145. tstrM2mScanDone strState;
  146. if(hif_receive(u32Addr, (uint8*)&strState, sizeof(tstrM2mScanDone), 0) == M2M_SUCCESS)
  147. {
  148. gu8ChNum = strState.u8NumofCh;
  149. if (gpfAppWifiCb)
  150. gpfAppWifiCb(M2M_WIFI_RESP_SCAN_DONE, &strState);
  151. }
  152. }
  153. else if (u8OpCode == M2M_WIFI_RESP_SCAN_RESULT)
  154. {
  155. tstrM2mWifiscanResult strScanResult;
  156. if(hif_receive(u32Addr, (uint8*)&strScanResult, sizeof(tstrM2mWifiscanResult), 0) == M2M_SUCCESS)
  157. {
  158. if (gpfAppWifiCb)
  159. gpfAppWifiCb(M2M_WIFI_RESP_SCAN_RESULT, &strScanResult);
  160. }
  161. }
  162. else if (u8OpCode == M2M_WIFI_RESP_CURRENT_RSSI)
  163. {
  164. if (hif_receive(u32Addr, rx_buf, 4, 0) == M2M_SUCCESS)
  165. {
  166. if (gpfAppWifiCb)
  167. gpfAppWifiCb(M2M_WIFI_RESP_CURRENT_RSSI, rx_buf);
  168. }
  169. }
  170. else if (u8OpCode == M2M_WIFI_RESP_CLIENT_INFO)
  171. {
  172. if (hif_receive(u32Addr, rx_buf, 4, 0) == M2M_SUCCESS)
  173. {
  174. if (gpfAppWifiCb)
  175. gpfAppWifiCb(M2M_WIFI_RESP_CLIENT_INFO, rx_buf);
  176. }
  177. }
  178. else if(u8OpCode == M2M_WIFI_RESP_PROVISION_INFO)
  179. {
  180. tstrM2MProvisionInfo strProvInfo;
  181. if(hif_receive(u32Addr, (uint8*)&strProvInfo, sizeof(tstrM2MProvisionInfo), 1) == M2M_SUCCESS)
  182. {
  183. if(gpfAppWifiCb)
  184. gpfAppWifiCb(M2M_WIFI_RESP_PROVISION_INFO, &strProvInfo);
  185. }
  186. }
  187. else if(u8OpCode == M2M_WIFI_RESP_DEFAULT_CONNECT)
  188. {
  189. tstrM2MDefaultConnResp strResp;
  190. if(hif_receive(u32Addr, (uint8*)&strResp, sizeof(tstrM2MDefaultConnResp), 1) == M2M_SUCCESS)
  191. {
  192. if(gpfAppWifiCb)
  193. gpfAppWifiCb(M2M_WIFI_RESP_DEFAULT_CONNECT, &strResp);
  194. }
  195. }
  196. else if (u8OpCode == M2M_WIFI_RESP_BLE_API_RECV)
  197. {
  198. //Read the length
  199. if(hif_receive(u32Addr, rx_buf, 2, 0) == M2M_SUCCESS)
  200. {
  201. uint16 u16BleMsgLen = (rx_buf[1] << 8) + rx_buf[0];
  202. tstrM2mBleApiMsg* bleRx = (tstrM2mBleApiMsg*)malloc(u16BleMsgLen + sizeof(tstrM2mBleApiMsg));
  203. if(bleRx != NULL)
  204. {
  205. bleRx->u16Len = u16BleMsgLen;
  206. //Read the rest of the message
  207. if (hif_receive(u32Addr+2, bleRx->data, bleRx->u16Len, 1)== M2M_SUCCESS)
  208. {
  209. if(gpfAppWifiCb)
  210. gpfAppWifiCb(M2M_WIFI_RESP_BLE_API_RECV, bleRx);
  211. }
  212. free(bleRx);
  213. }
  214. }
  215. }
  216. else if(u8OpCode == M2M_WIFI_RESP_GET_PRNG)
  217. {
  218. tstrPrng strPrng;
  219. if(hif_receive(u32Addr, (uint8*)&strPrng,sizeof(tstrPrng), 0) == M2M_SUCCESS)
  220. {
  221. if(hif_receive(u32Addr + sizeof(tstrPrng),strPrng.pu8RngBuff,strPrng.u16PrngSize, 1) == M2M_SUCCESS)
  222. {
  223. if(gpfAppWifiCb) {
  224. gpfAppWifiCb(M2M_WIFI_RESP_GET_PRNG,&strPrng);
  225. }
  226. }
  227. }
  228. }
  229. else if (u8OpCode == M2M_WIFI_RESP_SET_GAIN_TABLE)
  230. {
  231. tstrM2MGainTableRsp strGainRsp;
  232. if (hif_receive(u32Addr, (uint8*) &strGainRsp,sizeof(tstrM2MGainTableRsp), 0) == M2M_SUCCESS)
  233. {
  234. if (gpfAppWifiCb)
  235. gpfAppWifiCb(M2M_WIFI_RESP_SET_GAIN_TABLE, &strGainRsp);
  236. }
  237. }
  238. #ifdef ETH_MODE
  239. else if(u8OpCode == M2M_WIFI_RESP_ETHERNET_RX_PACKET)
  240. {
  241. if(hif_receive(u32Addr, rx_buf ,sizeof(tstrM2mIpRsvdPkt), 0) == M2M_SUCCESS)
  242. {
  243. tstrM2mIpRsvdPkt * pstrM2MIpRxPkt = (tstrM2mIpRsvdPkt*)rx_buf;
  244. tstrM2mIpCtrlBuf strM2mIpCtrlBuf;
  245. uint16 u16Offset = pstrM2MIpRxPkt->u16PktOffset;
  246. strM2mIpCtrlBuf.u16RemainigDataSize = pstrM2MIpRxPkt->u16PktSz;
  247. if((gpfAppEthCb) &&(gau8ethRcvBuf)&& (gu16ethRcvBufSize > 0))
  248. {
  249. while (strM2mIpCtrlBuf.u16RemainigDataSize > 0)
  250. {
  251. if(strM2mIpCtrlBuf.u16RemainigDataSize > gu16ethRcvBufSize)
  252. {
  253. strM2mIpCtrlBuf.u16DataSize = gu16ethRcvBufSize ;
  254. }
  255. else
  256. {
  257. strM2mIpCtrlBuf.u16DataSize = strM2mIpCtrlBuf.u16RemainigDataSize;
  258. }
  259. if(hif_receive(u32Addr+u16Offset, gau8ethRcvBuf, strM2mIpCtrlBuf.u16DataSize, 0) == M2M_SUCCESS)
  260. {
  261. strM2mIpCtrlBuf.u16RemainigDataSize -= strM2mIpCtrlBuf.u16DataSize;
  262. u16Offset += strM2mIpCtrlBuf.u16DataSize;
  263. gpfAppEthCb(M2M_WIFI_RESP_ETHERNET_RX_PACKET, gau8ethRcvBuf, &(strM2mIpCtrlBuf));
  264. }
  265. else
  266. {
  267. break;
  268. }
  269. }
  270. }
  271. }
  272. }
  273. #endif
  274. #ifdef CONF_MGMT
  275. else if(u8OpCode == M2M_WIFI_RESP_WIFI_RX_PACKET)
  276. {
  277. tstrM2MWifiRxPacketInfo strRxPacketInfo;
  278. if(u16DataSize >= sizeof(tstrM2MWifiRxPacketInfo)) {
  279. if(hif_receive(u32Addr, (uint8*)&strRxPacketInfo, sizeof(tstrM2MWifiRxPacketInfo), 0) == M2M_SUCCESS)
  280. {
  281. u16DataSize -= sizeof(tstrM2MWifiRxPacketInfo);
  282. if(u16DataSize > 0 && gstrMgmtCtrl.pu8Buf != NULL)
  283. {
  284. if(u16DataSize > (gstrMgmtCtrl.u16Sz + gstrMgmtCtrl.u16Offset))
  285. {
  286. u16DataSize = gstrMgmtCtrl.u16Sz;
  287. }
  288. u32Addr += sizeof(tstrM2MWifiRxPacketInfo) + gstrMgmtCtrl.u16Offset;
  289. if(hif_receive(u32Addr , gstrMgmtCtrl.pu8Buf, u16DataSize, 1) != M2M_SUCCESS)
  290. {
  291. u16DataSize = 0;
  292. }
  293. }
  294. if(gpfAppMonCb)
  295. gpfAppMonCb(&strRxPacketInfo, gstrMgmtCtrl.pu8Buf,u16DataSize);
  296. }
  297. } else {
  298. M2M_ERR("Incorrect mon data size %u\n", u16DataSize);
  299. }
  300. }
  301. #endif
  302. else
  303. {
  304. M2M_ERR("REQ Not defined %d\n",u8OpCode);
  305. }
  306. }
  307. sint8 m2m_wifi_download_mode()
  308. {
  309. sint8 ret = M2M_SUCCESS;
  310. /* Apply device specific initialization. */
  311. ret = nm_drv_init_download_mode(0);
  312. if(ret != M2M_SUCCESS) goto _EXIT0;
  313. enable_interrupts();
  314. _EXIT0:
  315. return ret;
  316. }
  317. static sint8 m2m_validate_ap_parameters(CONST tstrM2MAPConfig* pstrM2MAPConfig)
  318. {
  319. sint8 s8Ret = M2M_SUCCESS;
  320. /* Check for incoming pointer */
  321. if(pstrM2MAPConfig == NULL)
  322. {
  323. M2M_ERR("INVALID POINTER\n");
  324. s8Ret = M2M_ERR_FAIL;
  325. goto ERR1;
  326. }
  327. /* Check for SSID */
  328. if((m2m_strlen((uint8 *)pstrM2MAPConfig->au8SSID) <= 0) || (m2m_strlen((uint8 *)pstrM2MAPConfig->au8SSID) >= M2M_MAX_SSID_LEN))
  329. {
  330. M2M_ERR("INVALID SSID\n");
  331. s8Ret = M2M_ERR_FAIL;
  332. goto ERR1;
  333. }
  334. /* Check for Channel */
  335. if(pstrM2MAPConfig->u8ListenChannel > M2M_WIFI_CH_14 || pstrM2MAPConfig->u8ListenChannel < M2M_WIFI_CH_1)
  336. {
  337. M2M_ERR("INVALID CH\n");
  338. s8Ret = M2M_ERR_FAIL;
  339. goto ERR1;
  340. }
  341. /* Check for DHCP Server IP address */
  342. if(!(pstrM2MAPConfig->au8DHCPServerIP[0] || pstrM2MAPConfig->au8DHCPServerIP[1]))
  343. {
  344. if(!(pstrM2MAPConfig->au8DHCPServerIP[2]))
  345. {
  346. M2M_ERR("INVALID DHCP SERVER IP\n");
  347. s8Ret = M2M_ERR_FAIL;
  348. goto ERR1;
  349. }
  350. }
  351. /* Check for Security */
  352. if(pstrM2MAPConfig->u8SecType == M2M_WIFI_SEC_OPEN)
  353. {
  354. goto ERR1;
  355. }
  356. else if(pstrM2MAPConfig->u8SecType == M2M_WIFI_SEC_WEP)
  357. {
  358. /* Check for WEP Key index */
  359. if((pstrM2MAPConfig->u8KeyIndx <= 0) || (pstrM2MAPConfig->u8KeyIndx > WEP_KEY_MAX_INDEX))
  360. {
  361. M2M_ERR("INVALID KEY INDEX\n");
  362. s8Ret = M2M_ERR_FAIL;
  363. goto ERR1;
  364. }
  365. /* Check for WEP Key size */
  366. if( (pstrM2MAPConfig->u8KeySz != WEP_40_KEY_STRING_SIZE) &&
  367. (pstrM2MAPConfig->u8KeySz != WEP_104_KEY_STRING_SIZE)
  368. )
  369. {
  370. M2M_ERR("INVALID KEY SIZE\n");
  371. s8Ret = M2M_ERR_FAIL;
  372. goto ERR1;
  373. }
  374. /* Check for WEP Key */
  375. if((pstrM2MAPConfig->au8WepKey == NULL) || (m2m_strlen((uint8 *)pstrM2MAPConfig->au8WepKey) <= 0) || (m2m_strlen((uint8 *)pstrM2MAPConfig->au8WepKey) > WEP_104_KEY_STRING_SIZE))
  376. {
  377. M2M_ERR("INVALID WEP KEY\n");
  378. s8Ret = M2M_ERR_FAIL;
  379. goto ERR1;
  380. }
  381. }
  382. else
  383. {
  384. M2M_ERR("INVALID AUTHENTICATION MODE\n");
  385. s8Ret = M2M_ERR_FAIL;
  386. goto ERR1;
  387. }
  388. ERR1:
  389. return s8Ret;
  390. }
  391. static sint8 m2m_validate_scan_options(tstrM2MScanOption* ptstrM2MScanOption)
  392. {
  393. sint8 s8Ret = M2M_SUCCESS;
  394. /* Check for incoming pointer */
  395. if(ptstrM2MScanOption == NULL)
  396. {
  397. M2M_ERR("INVALID POINTER\n");
  398. s8Ret = M2M_ERR_FAIL;
  399. }
  400. else
  401. {
  402. /* Check for valid No of slots */
  403. if(ptstrM2MScanOption->u8NumOfSlot == 0)
  404. {
  405. M2M_ERR("INVALID No of scan slots!\n");
  406. s8Ret = M2M_ERR_FAIL;
  407. }
  408. /* Check for valid time of slots */
  409. if((ptstrM2MScanOption->u8SlotTime < 10) || (ptstrM2MScanOption->u8SlotTime > 250))
  410. {
  411. M2M_ERR("INVALID scan slot time!\n");
  412. s8Ret = M2M_ERR_FAIL;
  413. }
  414. /* Check for valid No of probe requests per slot */
  415. if((ptstrM2MScanOption->u8ProbesPerSlot == 0) || (ptstrM2MScanOption->u8ProbesPerSlot > M2M_SCAN_DEFAULT_NUM_PROBE))
  416. {
  417. M2M_ERR("INVALID No of probe requests per scan slot\n");
  418. s8Ret = M2M_ERR_FAIL;
  419. }
  420. /* Check for valid RSSI threshold */
  421. if(ptstrM2MScanOption->s8RssiThresh >= 0)
  422. {
  423. M2M_ERR("INVALID RSSI threshold %d \n",ptstrM2MScanOption->s8RssiThresh);
  424. s8Ret = M2M_ERR_FAIL;
  425. }
  426. }
  427. return s8Ret;
  428. }
  429. NMI_API sint8 m2m_wifi_ble_set_gain_table(uint8 table_idx)
  430. {
  431. sint8 s8Ret = M2M_ERR_FAIL;
  432. tstrM2MGainTable strGainTable = {0};
  433. strGainTable.u8GainTable = table_idx;
  434. s8Ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_GAIN_TABLE, (uint8 *)&strGainTable, sizeof(tstrM2MGainTable), NULL, 0, 0);
  435. return s8Ret;
  436. }
  437. sint8 m2m_wifi_init_hold(void)
  438. {
  439. sint8 ret = M2M_ERR_FAIL;
  440. /* Apply device specific initialization. */
  441. ret = nm_drv_init_hold(0);
  442. return ret;
  443. }
  444. sint8 m2m_wifi_init_start(tstrWifiInitParam * param)
  445. {
  446. tstrM2mRev strtmp;
  447. sint8 ret = M2M_SUCCESS;
  448. if(param == NULL) {
  449. ret = M2M_ERR_FAIL;
  450. goto _EXIT0;
  451. }
  452. gpfAppWifiCb = param->pfAppWifiCb;
  453. #ifdef ETH_MODE
  454. gpfAppEthCb = param->strEthInitParam.pfAppEthCb;
  455. gau8ethRcvBuf = param->strEthInitParam.au8ethRcvBuf;
  456. gu16ethRcvBufSize = param->strEthInitParam.u16ethRcvBufSize;
  457. #endif
  458. #ifdef CONF_MGMT
  459. gpfAppMonCb = param->pfAppMonCb;
  460. #endif
  461. /* Apply device specific initialization. */
  462. ret = nm_drv_init_start(NULL);
  463. if(ret != M2M_SUCCESS) goto _EXIT0;
  464. /* Initialize host interface module */
  465. ret = hif_init(NULL);
  466. if(ret != M2M_SUCCESS) goto _EXIT1;
  467. hif_register_cb(M2M_REQ_GROUP_WIFI,m2m_wifi_cb);
  468. M2M_INFO("Curr driver ver: %u.%u.%u\n", M2M_DRIVER_VERSION_MAJOR_NO, M2M_DRIVER_VERSION_MINOR_NO, M2M_DRIVER_VERSION_PATCH_NO);
  469. M2M_INFO("Curr driver HIF Level: (%u) %u.%u\n", M2M_HIF_BLOCK_VALUE, M2M_HIF_MAJOR_VALUE, M2M_HIF_MINOR_VALUE);
  470. ret = m2m_wifi_get_firmware_version(&strtmp);
  471. m2m_ota_get_firmware_version(&strtmp);
  472. if(ret == M2M_SUCCESS)
  473. {
  474. ret = hif_enable_access();
  475. if(ret == M2M_SUCCESS)
  476. {
  477. m2m_wifi_ble_set_gain_table(param->GainTableIndex);
  478. }
  479. }
  480. goto _EXIT0;
  481. _EXIT1:
  482. nm_drv_deinit(NULL);
  483. _EXIT0:
  484. return ret;
  485. }
  486. sint8 m2m_wifi_init(tstrWifiInitParam * param)
  487. {
  488. sint8 ret = M2M_SUCCESS;
  489. ret = m2m_wifi_init_hold();
  490. if (ret == M2M_SUCCESS)
  491. {
  492. ret = m2m_wifi_init_start(param);
  493. }
  494. return ret;
  495. }
  496. sint8 m2m_wifi_deinit(void * arg)
  497. {
  498. hif_deinit(NULL);
  499. nm_drv_deinit(NULL);
  500. return M2M_SUCCESS;
  501. }
  502. sint8 m2m_wifi_reinit_hold(void)
  503. {
  504. m2m_wifi_deinit(NULL);
  505. return m2m_wifi_init_hold();
  506. }
  507. sint8 m2m_wifi_reinit_start(tstrWifiInitParam * param)
  508. {
  509. return m2m_wifi_init_start(param);
  510. }
  511. sint8 m2m_wifi_reinit(tstrWifiInitParam * param)
  512. {
  513. sint8 ret = M2M_ERR_FAIL;
  514. ret = m2m_wifi_reinit_hold();
  515. if(ret == M2M_SUCCESS) {
  516. ret = m2m_wifi_reinit_start(param);
  517. }
  518. return ret;
  519. }
  520. void m2m_wifi_yield(void)
  521. {
  522. hif_yield();
  523. }
  524. sint8 m2m_wifi_handle_events(void * arg)
  525. {
  526. return hif_handle_isr();
  527. }
  528. sint8 m2m_wifi_default_connect(void)
  529. {
  530. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DEFAULT_CONNECT, NULL, 0,NULL, 0,0);
  531. }
  532. sint8 m2m_wifi_connect(char *pcSsid, uint8 u8SsidLen, uint8 u8SecType, void *pvAuthInfo, uint16 u16Ch)
  533. {
  534. return m2m_wifi_connect_sc(pcSsid, u8SsidLen, u8SecType, pvAuthInfo, u16Ch,0);
  535. }
  536. sint8 m2m_wifi_connect_sc(char *pcSsid, uint8 u8SsidLen, uint8 u8SecType, void *pvAuthInfo, uint16 u16Ch, uint8 u8NoSaveCred)
  537. {
  538. sint8 ret = M2M_SUCCESS;
  539. tstrM2mWifiConnect strConnect;
  540. tstrM2MWifiSecInfo *pstrAuthInfo;
  541. if(u8SecType != M2M_WIFI_SEC_OPEN)
  542. {
  543. if(pvAuthInfo == NULL)
  544. {
  545. M2M_ERR("Key is not valid\n");
  546. ret = M2M_ERR_FAIL;
  547. goto ERR1;
  548. }
  549. if((u8SecType == M2M_WIFI_SEC_WPA_PSK) && (m2m_strlen(pvAuthInfo) == (M2M_MAX_PSK_LEN-1)))
  550. {
  551. uint8 i = 0;
  552. uint8* pu8Psk = (uint8*)pvAuthInfo;
  553. while(i < (M2M_MAX_PSK_LEN-1))
  554. {
  555. if(pu8Psk[i]<'0' || (pu8Psk[i]>'9' && pu8Psk[i] < 'A')|| (pu8Psk[i]>'F' && pu8Psk[i] < 'a') || pu8Psk[i] > 'f')
  556. {
  557. M2M_ERR("Invalid Key\n");
  558. ret = M2M_ERR_FAIL;
  559. goto ERR1;
  560. }
  561. i++;
  562. }
  563. }
  564. }
  565. if((u8SsidLen<=0)||(u8SsidLen>=M2M_MAX_SSID_LEN))
  566. {
  567. M2M_ERR("SSID LEN INVALID\n");
  568. ret = M2M_ERR_FAIL;
  569. goto ERR1;
  570. }
  571. if(u16Ch < M2M_WIFI_CH_1 || u16Ch > M2M_WIFI_CH_14)
  572. {
  573. if(u16Ch!=M2M_WIFI_CH_ALL)
  574. {
  575. M2M_ERR("CH INVALID\n");
  576. ret = M2M_ERR_FAIL;
  577. goto ERR1;
  578. }
  579. }
  580. m2m_memcpy(strConnect.au8SSID, (uint8*)pcSsid, u8SsidLen);
  581. strConnect.au8SSID[u8SsidLen] = 0;
  582. strConnect.u16Ch = NM_BSP_B_L_16(u16Ch);
  583. /* Credentials will be Not be saved if u8NoSaveCred is set */
  584. strConnect.u8NoSaveCred = u8NoSaveCred ? 1:0;
  585. pstrAuthInfo = &strConnect.strSec;
  586. pstrAuthInfo->u8SecType = u8SecType;
  587. if(u8SecType == M2M_WIFI_SEC_WEP)
  588. {
  589. tstrM2mWifiWepParams * pstrWepParams = (tstrM2mWifiWepParams*)pvAuthInfo;
  590. tstrM2mWifiWepParams *pstrWep = &pstrAuthInfo->uniAuth.strWepInfo;
  591. pstrWep->u8KeyIndx =pstrWepParams->u8KeyIndx-1;
  592. if(pstrWep->u8KeyIndx >= WEP_KEY_MAX_INDEX)
  593. {
  594. M2M_ERR("Invalid Wep key index %d\n", pstrWep->u8KeyIndx);
  595. ret = M2M_ERR_FAIL;
  596. goto ERR1;
  597. }
  598. pstrWep->u8KeySz = pstrWepParams->u8KeySz-1;
  599. if ((pstrWep->u8KeySz != WEP_40_KEY_STRING_SIZE)&& (pstrWep->u8KeySz != WEP_104_KEY_STRING_SIZE))
  600. {
  601. M2M_ERR("Invalid Wep key length %d\n", pstrWep->u8KeySz);
  602. ret = M2M_ERR_FAIL;
  603. goto ERR1;
  604. }
  605. m2m_memcpy((uint8*)pstrWep->au8WepKey,(uint8*)pstrWepParams->au8WepKey, pstrWepParams->u8KeySz);
  606. pstrWep->au8WepKey[pstrWepParams->u8KeySz] = 0;
  607. }
  608. else if(u8SecType == M2M_WIFI_SEC_WPA_PSK)
  609. {
  610. uint16 u16KeyLen = m2m_strlen((uint8*)pvAuthInfo);
  611. if((u16KeyLen <= 0)||(u16KeyLen >= M2M_MAX_PSK_LEN))
  612. {
  613. M2M_ERR("Incorrect PSK key length\n");
  614. ret = M2M_ERR_FAIL;
  615. goto ERR1;
  616. }
  617. m2m_memcpy(pstrAuthInfo->uniAuth.au8PSK, (uint8*)pvAuthInfo, u16KeyLen + 1);
  618. }
  619. else if(u8SecType == M2M_WIFI_SEC_802_1X)
  620. {
  621. m2m_memcpy((uint8*)&pstrAuthInfo->uniAuth.strCred1x, (uint8*)pvAuthInfo, sizeof(tstr1xAuthCredentials));
  622. }
  623. else if(u8SecType == M2M_WIFI_SEC_OPEN)
  624. {
  625. }
  626. else
  627. {
  628. M2M_ERR("undefined sec type\n");
  629. ret = M2M_ERR_FAIL;
  630. goto ERR1;
  631. }
  632. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CONNECT, (uint8*)&strConnect, sizeof(tstrM2mWifiConnect),NULL, 0,0);
  633. ERR1:
  634. return ret;
  635. }
  636. sint8 m2m_wifi_disconnect(void)
  637. {
  638. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DISCONNECT, NULL, 0, NULL, 0,0);
  639. }
  640. sint8 m2m_wifi_set_mac_address(uint8 au8MacAddress[6])
  641. {
  642. tstrM2mSetMacAddress strTmp;
  643. m2m_memcpy((uint8*) strTmp.au8Mac, (uint8*) au8MacAddress, 6);
  644. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_MAC_ADDRESS,
  645. (uint8*) &strTmp, sizeof(tstrM2mSetMacAddress), NULL, 0,0);
  646. }
  647. sint8 m2m_wifi_set_static_ip(tstrM2MIPConfig * pstrStaticIPConf)
  648. {
  649. pstrStaticIPConf->u32DNS = NM_BSP_B_L_32(pstrStaticIPConf->u32DNS);
  650. pstrStaticIPConf->u32Gateway = NM_BSP_B_L_32(pstrStaticIPConf->u32Gateway);
  651. pstrStaticIPConf->u32StaticIP = NM_BSP_B_L_32(
  652. pstrStaticIPConf->u32StaticIP);
  653. pstrStaticIPConf->u32SubnetMask = NM_BSP_B_L_32(
  654. pstrStaticIPConf->u32SubnetMask);
  655. return hif_send(M2M_REQ_GROUP_IP, M2M_IP_REQ_STATIC_IP_CONF,
  656. (uint8*) pstrStaticIPConf, sizeof(tstrM2MIPConfig), NULL, 0,0);
  657. }
  658. sint8 m2m_wifi_request_dhcp_client(void)
  659. {
  660. /*legacy API should be removed */
  661. return 0;
  662. }
  663. sint8 m2m_wifi_request_dhcp_server(uint8* addr)
  664. {
  665. /*legacy API should be removed */
  666. return 0;
  667. }
  668. /*!
  669. @fn NMI_API sint8 m2m_wifi_set_lsn_int(tstrM2mLsnInt * pstrM2mLsnInt);
  670. @brief Set the Wi-Fi listen interval for power save operation. It is represented in units
  671. of AP Beacon periods.
  672. @param [in] pstrM2mLsnInt
  673. Structure holding the listen interval configurations.
  674. @return The function SHALL return 0 for success and a negative value otherwise.
  675. @sa tstrM2mLsnInt , m2m_wifi_set_sleep_mode
  676. @pre m2m_wifi_set_sleep_mode shall be called first
  677. @warning The Function called once after initialization.
  678. */
  679. sint8 m2m_wifi_enable_dhcp(uint8 u8DhcpEn )
  680. {
  681. uint8 u8Req;
  682. u8Req = u8DhcpEn ? M2M_IP_REQ_ENABLE_DHCP : M2M_IP_REQ_DISABLE_DHCP;
  683. return hif_send(M2M_REQ_GROUP_IP, u8Req, NULL, 0, NULL, 0, 0);
  684. }
  685. sint8 m2m_wifi_set_lsn_int(tstrM2mLsnInt* pstrM2mLsnInt)
  686. {
  687. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_LSN_INT, (uint8*)pstrM2mLsnInt, sizeof(tstrM2mLsnInt), NULL, 0, 0);
  688. }
  689. sint8 m2m_wifi_set_cust_InfoElement(uint8* pau8M2mCustInfoElement)
  690. {
  691. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CUST_INFO_ELEMENT, (uint8*)pau8M2mCustInfoElement, pau8M2mCustInfoElement[0]+1, NULL, 0, 0);
  692. }
  693. sint8 m2m_wifi_set_scan_options(tstrM2MScanOption* ptstrM2MScanOption)
  694. {
  695. sint8 s8Ret = M2M_ERR_FAIL;
  696. if(m2m_validate_scan_options (ptstrM2MScanOption) == M2M_SUCCESS)
  697. {
  698. s8Ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_SCAN_OPTION, (uint8*)ptstrM2MScanOption, sizeof(tstrM2MScanOption),NULL, 0,0);
  699. }
  700. return s8Ret;
  701. }
  702. sint8 m2m_wifi_set_scan_region(uint16 ScanRegion)
  703. {
  704. sint8 s8Ret = M2M_ERR_FAIL;
  705. tstrM2MScanRegion strScanRegion;
  706. strScanRegion.u16ScanRegion = ScanRegion;
  707. s8Ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_SCAN_REGION, (uint8*)&strScanRegion, sizeof(tstrM2MScanRegion),NULL, 0,0);
  708. return s8Ret;
  709. }
  710. sint8 m2m_wifi_request_scan(uint8 ch)
  711. {
  712. sint8 s8Ret = M2M_SUCCESS;
  713. if(((ch >= M2M_WIFI_CH_1) && (ch <= M2M_WIFI_CH_14)) || (ch == M2M_WIFI_CH_ALL))
  714. {
  715. tstrM2MScan strtmp;
  716. strtmp.u8ChNum = ch;
  717. s8Ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SCAN, (uint8*)&strtmp, sizeof(tstrM2MScan),NULL, 0,0);
  718. }
  719. else
  720. {
  721. s8Ret = M2M_ERR_INVALID_ARG;
  722. }
  723. return s8Ret;
  724. }
  725. sint8 m2m_wifi_request_scan_passive(uint8 ch)
  726. {
  727. sint8 s8Ret = M2M_SUCCESS;
  728. if(((ch >= M2M_WIFI_CH_1) && (ch <= M2M_WIFI_CH_14)) || (ch == M2M_WIFI_CH_ALL))
  729. {
  730. tstrM2MScan strtmp;
  731. strtmp.u8ChNum = ch;
  732. s8Ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_PASSIVE_SCAN, (uint8*)&strtmp, sizeof(tstrM2MScan),NULL, 0,0);
  733. }
  734. else
  735. {
  736. s8Ret = M2M_ERR_INVALID_ARG;
  737. }
  738. return s8Ret;
  739. }
  740. sint8 m2m_wifi_wps(uint8 u8TriggerType,const char *pcPinNumber)
  741. {
  742. tstrM2MWPSConnect strtmp;
  743. strtmp.u8TriggerType = u8TriggerType;
  744. /*If WPS is using PIN METHOD*/
  745. if (u8TriggerType == WPS_PIN_TRIGGER)
  746. m2m_memcpy ((uint8*)strtmp.acPinNumber,(uint8*) pcPinNumber,8);
  747. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_WPS, (uint8*)&strtmp,sizeof(tstrM2MWPSConnect), NULL, 0,0);
  748. }
  749. sint8 m2m_wifi_wps_disable(void)
  750. {
  751. sint8 ret = M2M_SUCCESS;
  752. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DISABLE_WPS, NULL,0, NULL, 0, 0);
  753. return ret;
  754. }
  755. #if 0
  756. /*
  757. * These two functions m2m_wifi_req_client_ctrl and m2m_wifi_req_server_init are for a mode in which two WINC ICs
  758. * communicate with each other via probe request and probe response frames. This mode is not supported in WINC fw.
  759. */
  760. sint8 m2m_wifi_req_client_ctrl(uint8 u8Cmd)
  761. {
  762. sint8 ret = M2M_SUCCESS;
  763. #ifdef _PS_SERVER_
  764. tstrM2Mservercmd strCmd;
  765. strCmd.u8cmd = u8Cmd;
  766. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CLIENT_CTRL, (uint8*)&strCmd, sizeof(tstrM2Mservercmd), NULL, 0, 0);
  767. #else
  768. M2M_ERR("_PS_SERVER_ is not defined\n");
  769. #endif
  770. return ret;
  771. }
  772. sint8 m2m_wifi_req_server_init(uint8 ch)
  773. {
  774. sint8 ret = M2M_SUCCESS;
  775. #ifdef _PS_SERVER_
  776. tstrM2mServerInit strServer;
  777. strServer.u8Channel = ch;
  778. ret = hif_send(M2M_REQ_GROUP_WIFI,M2M_WIFI_REQ_SERVER_INIT, (uint8*)&strServer, sizeof(tstrM2mServerInit), NULL, 0, 0);
  779. #else
  780. M2M_ERR("_PS_SERVER_ is not defined\n");
  781. #endif
  782. return ret;
  783. }
  784. #endif
  785. sint8 m2m_wifi_p2p(uint8 u8Channel)
  786. {
  787. sint8 ret = M2M_SUCCESS;
  788. if((u8Channel == M2M_WIFI_CH_1) || (u8Channel == M2M_WIFI_CH_6) || (u8Channel == M2M_WIFI_CH_11))
  789. {
  790. tstrM2MP2PConnect strtmp;
  791. strtmp.u8ListenChannel = u8Channel;
  792. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_ENABLE_P2P, (uint8*)&strtmp, sizeof(tstrM2MP2PConnect), NULL, 0,0);
  793. }
  794. else
  795. {
  796. M2M_ERR("Listen channel should only be 1, 6 or 11\n");
  797. ret = M2M_ERR_FAIL;
  798. }
  799. return ret;
  800. }
  801. sint8 m2m_wifi_p2p_disconnect(void)
  802. {
  803. sint8 ret = M2M_SUCCESS;
  804. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DISABLE_P2P, NULL, 0, NULL, 0, 0);
  805. return ret;
  806. }
  807. sint8 m2m_wifi_enable_ap(CONST tstrM2MAPConfig* pstrM2MAPConfig)
  808. {
  809. sint8 ret = M2M_ERR_FAIL;
  810. if(M2M_SUCCESS == m2m_validate_ap_parameters(pstrM2MAPConfig))
  811. {
  812. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_ENABLE_AP, (uint8 *)pstrM2MAPConfig, sizeof(tstrM2MAPConfig), NULL, 0, 0);
  813. }
  814. return ret;
  815. }
  816. sint8 m2m_wifi_disable_ap(void)
  817. {
  818. sint8 ret = M2M_SUCCESS;
  819. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DISABLE_AP, NULL, 0, NULL, 0, 0);
  820. return ret;
  821. }
  822. /*!
  823. @fn NMI_API sint8 m2m_wifi_req_curr_rssi(void);
  824. @brief Request the current RSSI for the current connected AP,
  825. the response received in wifi_cb M2M_WIFI_RESP_CURRENT_RSSI
  826. @sa M2M_WIFI_RESP_CURRENT_RSSI
  827. @return The function shall return M2M_SUCCESS for success and a negative value otherwise.
  828. */
  829. sint8 m2m_wifi_req_curr_rssi(void)
  830. {
  831. sint8 ret = M2M_SUCCESS;
  832. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_CURRENT_RSSI, NULL, 0, NULL,0, 0);
  833. return ret;
  834. }
  835. sint8 m2m_wifi_req_restrict_ble(void)
  836. {
  837. sint8 ret = M2M_SUCCESS;
  838. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_RESTRICT_BLE,NULL, 0, NULL, 0, 0);
  839. return ret;
  840. }
  841. sint8 m2m_wifi_req_unrestrict_ble(void)
  842. {
  843. sint8 ret = M2M_SUCCESS;
  844. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_UNRESTRICT_BLE,NULL, 0, NULL, 0, 0);
  845. return ret;
  846. }
  847. sint8 m2m_wifi_send_ethernet_pkt(uint8* pu8Packet,uint16 u16PacketSize)
  848. {
  849. sint8 s8Ret = -1;
  850. if((pu8Packet != NULL)&&(u16PacketSize>0))
  851. {
  852. tstrM2MWifiTxPacketInfo strTxPkt;
  853. strTxPkt.u16PacketSize = u16PacketSize;
  854. strTxPkt.u16HeaderLength = M2M_ETHERNET_HDR_LEN;
  855. s8Ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SEND_ETHERNET_PACKET | M2M_REQ_DATA_PKT,
  856. (uint8*)&strTxPkt, sizeof(tstrM2MWifiTxPacketInfo), pu8Packet, u16PacketSize, M2M_ETHERNET_HDR_OFFSET - M2M_HIF_HDR_OFFSET);
  857. }
  858. return s8Ret;
  859. }
  860. /*!
  861. @fn NMI_API sint8 m2m_wifi_get_otp_mac_address(uint8 *pu8MacAddr, uint8 * pu8IsValid);
  862. @brief Request the MAC address stored on the OTP (one time programmable) memory of the device.
  863. (the function is Blocking until response received)
  864. @param [out] pu8MacAddr
  865. Output MAC address buffer of 6 bytes size. Valid only if *pu8Valid=1.
  866. @param [out] pu8IsValid
  867. A output boolean value to indicate the validity of pu8MacAddr in OTP.
  868. Output zero if the OTP memory is not programmed, non-zero otherwise.
  869. @return The function shall return M2M_SUCCESS for success and a negative value otherwise.
  870. @sa m2m_wifi_get_mac_address
  871. @pre m2m_wifi_init required to call any WIFI/socket function
  872. */
  873. sint8 m2m_wifi_get_otp_mac_address(uint8 *pu8MacAddr, uint8* pu8IsValid)
  874. {
  875. sint8 ret = M2M_SUCCESS;
  876. ret = hif_chip_wake();
  877. if(ret == M2M_SUCCESS)
  878. {
  879. ret = nmi_get_otp_mac_address(pu8MacAddr, pu8IsValid);
  880. if(ret == M2M_SUCCESS)
  881. {
  882. ret = hif_chip_sleep();
  883. }
  884. }
  885. return ret;
  886. }
  887. /*!
  888. @fn NMI_API sint8 m2m_wifi_get_mac_address(uint8 *pu8MacAddr)
  889. @brief Request the current MAC address of the device (the working mac address).
  890. (the function is Blocking until response received)
  891. @param [out] pu8MacAddr
  892. Output MAC address buffer of 6 bytes size.
  893. @return The function shall return M2M_SUCCESS for success and a negative value otherwise.
  894. @sa m2m_wifi_get_otp_mac_address
  895. @pre m2m_wifi_init required to call any WIFI/socket function
  896. */
  897. sint8 m2m_wifi_get_mac_address(uint8 *pu8MacAddr)
  898. {
  899. sint8 ret = M2M_SUCCESS;
  900. ret = hif_chip_wake();
  901. if(ret == M2M_SUCCESS)
  902. {
  903. ret = nmi_get_mac_address(pu8MacAddr);
  904. if(ret == M2M_SUCCESS)
  905. {
  906. ret = hif_chip_sleep();
  907. }
  908. }
  909. return ret;
  910. }
  911. /*!
  912. @fn NMI_API sint8 m2m_wifi_req_scan_result(uint8 index);
  913. @brief Reads the AP information from the Scan Result list with the given index,
  914. the response received in wifi_cb M2M_WIFI_RESP_SCAN_RESULT,
  915. the response pointer should be casted with tstrM2mWifiscanResult structure
  916. @param [in] index
  917. Index for the requested result, the index range start from 0 till number of AP's found
  918. @sa tstrM2mWifiscanResult,m2m_wifi_get_num_ap_found,m2m_wifi_request_scan
  919. @return The function shall return @ref M2M_SUCCESS for success and a negative value otherwise
  920. @pre m2m_wifi_request_scan need to be called first, then m2m_wifi_get_num_ap_found
  921. to get the number of AP's found
  922. @warning Function used only in STA mode only. the scan result updated only if scan request called,
  923. else it will be cashed in firmware for the host scan request result,
  924. which mean if large delay occur between the scan request and the scan result request,
  925. the result will not be up-to-date
  926. */
  927. sint8 m2m_wifi_req_scan_result(uint8 index)
  928. {
  929. sint8 ret = M2M_SUCCESS;
  930. tstrM2mReqScanResult strReqScanRlt;
  931. strReqScanRlt.u8Index = index;
  932. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SCAN_RESULT, (uint8*) &strReqScanRlt, sizeof(tstrM2mReqScanResult), NULL, 0, 0);
  933. return ret;
  934. }
  935. /*!
  936. @fn NMI_API uint8 m2m_wifi_get_num_ap_found(void);
  937. @brief Reads the number of AP's found in the last Scan Request,
  938. The function read the number of AP's from global variable which updated in the
  939. wifi_cb in M2M_WIFI_RESP_SCAN_DONE.
  940. @sa m2m_wifi_request_scan
  941. @return Return the number of AP's found in the last Scan Request.
  942. @pre m2m_wifi_request_scan need to be called first
  943. @warning That function need to be called in the wifi_cb in M2M_WIFI_RESP_SCAN_DONE,
  944. calling that function in any other place will return undefined/undated numbers.
  945. Function used only in STA mode only.
  946. */
  947. uint8 m2m_wifi_get_num_ap_found(void)
  948. {
  949. return gu8ChNum;
  950. }
  951. /*!
  952. @fn NMI_API uint8 m2m_wifi_get_sleep_mode(void);
  953. @brief Get the current Power save mode.
  954. @return The current operating power saving mode.
  955. @sa tenuPowerSaveModes , m2m_wifi_set_sleep_mode
  956. */
  957. uint8 m2m_wifi_get_sleep_mode(void)
  958. {
  959. return hif_get_sleep_mode();
  960. }
  961. /*!
  962. @fn NMI_API sint8 m2m_wifi_set_sleep_mode(uint8 PsTyp, uint8 BcastEn);
  963. @brief Set the power saving mode for the WINC3400.
  964. @param [in] PsTyp
  965. Desired power saving mode. Supported types are defined in tenuPowerSaveModes.
  966. @param [in] BcastEn
  967. Broadcast reception enable flag.
  968. If it is 1, the WINC3400 must be awake each DTIM Beacon for receiving Broadcast traffic.
  969. If it is 0, the WINC3400 will not wakeup at the DTIM Beacon, but its wakeup depends only
  970. on the the configured Listen Interval.
  971. @return The function SHALL return 0 for success and a negative value otherwise.
  972. @sa tenuPowerSaveModes
  973. @warning The function called once after initialization.
  974. */
  975. sint8 m2m_wifi_set_sleep_mode(uint8 PsTyp, uint8 BcastEn)
  976. {
  977. sint8 ret = M2M_SUCCESS;
  978. tstrM2mPsType strPs;
  979. strPs.u8PsType = PsTyp;
  980. strPs.u8BcastEn = BcastEn;
  981. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SLEEP, (uint8*) &strPs,sizeof(tstrM2mPsType), NULL, 0, 0);
  982. M2M_INFO("POWER SAVE %d\n",PsTyp);
  983. hif_set_sleep_mode(PsTyp);
  984. return ret;
  985. }
  986. /*!
  987. @fn NMI_API sint8 m2m_wifi_request_sleep(void)
  988. @brief Request from WINC3400 device to Sleep for specific time in the M2M_PS_MANUAL Power save mode (only).
  989. @param [in] u32SlpReqTime
  990. Request Sleep in ms
  991. @return The function SHALL return M2M_SUCCESS for success and a negative value otherwise.
  992. @sa tenuPowerSaveModes , m2m_wifi_set_sleep_mode
  993. @warning This API is currently unsupported on the WINC3400
  994. */
  995. sint8 m2m_wifi_request_sleep(uint32 u32SlpReqTime)
  996. {
  997. sint8 ret = M2M_SUCCESS;
  998. uint8 psType;
  999. psType = hif_get_sleep_mode();
  1000. if(psType == M2M_PS_MANUAL)
  1001. {
  1002. tstrM2mSlpReqTime strPs;
  1003. strPs.u32SleepTime = u32SlpReqTime;
  1004. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DOZE, (uint8*) &strPs,sizeof(tstrM2mSlpReqTime), NULL, 0, 0);
  1005. }
  1006. return ret;
  1007. }
  1008. /*!
  1009. @fn NMI_API sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameLength);
  1010. @brief Set the WINC3400 device name which is used as P2P device name.
  1011. @param [in] pu8DeviceName
  1012. Buffer holding the device name.
  1013. @param [in] u8DeviceNameLength
  1014. Length of the device name.
  1015. @return The function SHALL return M2M_SUCCESS for success and a negative value otherwise.
  1016. @warning The Function called once after initialization.
  1017. */
  1018. sint8 m2m_wifi_set_device_name(uint8 *pu8DeviceName, uint8 u8DeviceNameLength)
  1019. {
  1020. tstrM2MDeviceNameConfig strDeviceName;
  1021. if(u8DeviceNameLength >= M2M_DEVICE_NAME_MAX)
  1022. {
  1023. u8DeviceNameLength = M2M_DEVICE_NAME_MAX;
  1024. }
  1025. //pu8DeviceName[u8DeviceNameLength] = '\0';
  1026. u8DeviceNameLength ++;
  1027. m2m_memcpy(strDeviceName.au8DeviceName, pu8DeviceName, u8DeviceNameLength);
  1028. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_DEVICE_NAME,
  1029. (uint8*)&strDeviceName, sizeof(tstrM2MDeviceNameConfig), NULL, 0,0);
  1030. }
  1031. /*!
  1032. @fn \
  1033. uint32 m2m_wifi_get_chipId(void)
  1034. @brief
  1035. Get the WINC Chip ID.
  1036. @return
  1037. The function SHALL return chipID >0 or 0 for failure.
  1038. */
  1039. uint32 m2m_wifi_get_chipId(void)
  1040. {
  1041. return nmi_get_chipid();
  1042. }
  1043. /*!
  1044. @fn sint8 m2m_wifi_get_firmware_version(tstrM2mRev* pstrRev)
  1045. @brief
  1046. Synchronous API to obtain the firmware version currently running on the WINC IC
  1047. @param [out] pstrRev
  1048. pointer holds address of structure "tstrM2mRev" that contains the firmware version parameters
  1049. @return
  1050. The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
  1051. */
  1052. sint8 m2m_wifi_get_firmware_version(tstrM2mRev *pstrRev)
  1053. {
  1054. sint8 ret = M2M_SUCCESS;
  1055. ret = hif_chip_wake();
  1056. if(ret == M2M_SUCCESS)
  1057. {
  1058. ret = nm_get_firmware_full_info(pstrRev);
  1059. hif_chip_sleep();
  1060. }
  1061. return ret;
  1062. }
  1063. /*!
  1064. @fn sint8 m2m_wifi_check_ota_rb(void);
  1065. @brief
  1066. Synchronous API to check presence and compatibility of the WINC image that is stored in the inactive flash partition.
  1067. This is the image that would run on the WINC IC if @ref m2m_ota_switch_firmware or @ref m2m_ota_rollback were called,
  1068. followed by a reset of the WINC IC.
  1069. @return
  1070. The function SHALL return @ref M2M_SUCCESS for compatible image and a negative value otherwise.
  1071. */
  1072. sint8 m2m_wifi_check_ota_rb(void)
  1073. {
  1074. sint8 ret = M2M_SUCCESS;
  1075. uint16 ota_hif_info = 0;
  1076. ret = nm_get_hif_info(NULL, &ota_hif_info);
  1077. if(ret == M2M_SUCCESS)
  1078. {
  1079. ret = hif_check_compatibility(ota_hif_info);
  1080. }
  1081. return ret;
  1082. }
  1083. /*!
  1084. @fn \
  1085. NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev *pstrRev);
  1086. @brief
  1087. Synchronous API to obtain the firmware version of the WINC image that is stored in the inactive flash partition.
  1088. This is the image that would run on the WINC IC if @ref m2m_ota_switch_firmware or @ref m2m_ota_rollback were called,
  1089. followed by a reset of the WINC IC.
  1090. @param [out] pstrRev
  1091. pointer holds address of structure "tstrM2mRev" that contains the ota fw version parameters
  1092. @return
  1093. The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
  1094. */
  1095. NMI_API sint8 m2m_ota_get_firmware_version(tstrM2mRev * pstrRev)
  1096. {
  1097. sint8 ret = M2M_SUCCESS;
  1098. ret = hif_chip_wake();
  1099. if(ret == M2M_SUCCESS)
  1100. {
  1101. ret = nm_get_ota_firmware_info(pstrRev);
  1102. hif_chip_sleep();
  1103. }
  1104. return ret;
  1105. }
  1106. #ifdef CONF_MGMT
  1107. sint8 m2m_wifi_enable_monitoring_mode(tstrM2MWifiMonitorModeCtrl *pstrMtrCtrl, uint8 *pu8PayloadBuffer,
  1108. uint16 u16BufferSize, uint16 u16DataOffset)
  1109. {
  1110. sint8 s8Ret = -1;
  1111. if((pstrMtrCtrl->u8ChannelID >= M2M_WIFI_CH_1) && (pstrMtrCtrl->u8ChannelID <= M2M_WIFI_CH_14))
  1112. {
  1113. gstrMgmtCtrl.pu8Buf = pu8PayloadBuffer;
  1114. gstrMgmtCtrl.u16Sz = u16BufferSize;
  1115. gstrMgmtCtrl.u16Offset = u16DataOffset;
  1116. s8Ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_ENABLE_MONITORING,
  1117. (uint8*)pstrMtrCtrl, sizeof(tstrM2MWifiMonitorModeCtrl), NULL, 0,0);
  1118. }
  1119. return s8Ret;
  1120. }
  1121. sint8 m2m_wifi_disable_monitoring_mode(void)
  1122. {
  1123. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_DISABLE_MONITORING, NULL, 0, NULL, 0,0);
  1124. }
  1125. sint8 m2m_wifi_send_wlan_pkt(uint8 *pu8WlanPacket, uint16 u16WlanHeaderLength, uint16 u16WlanPktSize)
  1126. {
  1127. sint8 s8Ret = -1;
  1128. if(pu8WlanPacket != NULL)
  1129. {
  1130. tstrM2MWifiTxPacketInfo strTxPkt;
  1131. strTxPkt.u16PacketSize = u16WlanPktSize;
  1132. strTxPkt.u16HeaderLength = u16WlanHeaderLength;
  1133. s8Ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SEND_WIFI_PACKET | M2M_REQ_DATA_PKT,
  1134. (uint8*)&strTxPkt, sizeof(tstrM2MWifiTxPacketInfo), pu8WlanPacket, u16WlanPktSize, sizeof(tstrM2MWifiTxPacketInfo));
  1135. }
  1136. return s8Ret;
  1137. }
  1138. #endif
  1139. sint8 m2m_wifi_start_provision_mode(tstrM2MAPConfig *pstrAPConfig, char *pcHttpServerDomainName, uint8 bEnableHttpRedirect)
  1140. {
  1141. sint8 s8Ret = M2M_ERR_FAIL;
  1142. if((pstrAPConfig != NULL))
  1143. {
  1144. tstrM2MProvisionModeConfig strProvConfig;
  1145. if(M2M_SUCCESS == m2m_validate_ap_parameters(pstrAPConfig))
  1146. {
  1147. m2m_memcpy((uint8*)&strProvConfig.strApConfig, (uint8*)pstrAPConfig, sizeof(tstrM2MAPConfig));
  1148. if((m2m_strlen((uint8 *)pcHttpServerDomainName) <= 0) || (NULL == pcHttpServerDomainName))
  1149. {
  1150. M2M_ERR("INVALID DOMAIN NAME\n");
  1151. goto ERR1;
  1152. }
  1153. m2m_memcpy((uint8*)strProvConfig.acHttpServerDomainName, (uint8*)pcHttpServerDomainName, 64);
  1154. strProvConfig.u8EnableRedirect = bEnableHttpRedirect;
  1155. s8Ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_START_PROVISION_MODE | M2M_REQ_DATA_PKT,
  1156. (uint8*)&strProvConfig, sizeof(tstrM2MProvisionModeConfig), NULL, 0, 0);
  1157. }
  1158. else
  1159. {
  1160. /*goto ERR1;*/
  1161. }
  1162. }
  1163. ERR1:
  1164. return s8Ret;
  1165. }
  1166. sint8 m2m_wifi_stop_provision_mode(void)
  1167. {
  1168. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_STOP_PROVISION_MODE, NULL, 0, NULL, 0, 0);
  1169. }
  1170. sint8 m2m_wifi_get_connection_info(void)
  1171. {
  1172. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_GET_CONN_INFO, NULL, 0, NULL, 0, 0);
  1173. }
  1174. sint8 m2m_wifi_set_sytem_time(uint32 u32UTCSeconds)
  1175. {
  1176. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_SYS_TIME, (uint8*)&u32UTCSeconds, sizeof(tstrSystemTime), NULL, 0, 0);
  1177. }
  1178. /*!
  1179. * @fn NMI_API sint8 m2m_wifi_get_sytem_time(void);
  1180. * @see m2m_wifi_enable_sntp
  1181. tstrSystemTime
  1182. * @note get the system time from the sntp client
  1183. * using the API \ref m2m_wifi_get_sytem_time.
  1184. * @return The function returns @ref M2M_SUCCESS for successful operations and a negative value otherwise.
  1185. */
  1186. sint8 m2m_wifi_get_sytem_time(void)
  1187. {
  1188. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_GET_SYS_TIME, NULL,0, NULL, 0, 0);
  1189. }
  1190. sint8 m2m_wifi_enable_sntp(uint8 bEnable)
  1191. {
  1192. uint8 u8Req;
  1193. u8Req = bEnable ? M2M_WIFI_REQ_ENABLE_SNTP_CLIENT : M2M_WIFI_REQ_DISABLE_SNTP_CLIENT;
  1194. return hif_send(M2M_REQ_GROUP_WIFI, u8Req, NULL, 0, NULL, 0, 0);
  1195. }
  1196. /*!
  1197. @fn NMI_API sint8 m2m_wifi_set_power_profile(uint8 u8PwrMode);
  1198. @brief Change the power profile mode
  1199. @param [in] u8PwrMode
  1200. Change the WINC power profile to different mode
  1201. PWR_LOW1/PWR_LOW2/PWR_HIGH/PWR_AUTO (tenuM2mPwrMode)
  1202. @return The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
  1203. @sa tenuM2mPwrMode
  1204. @pre m2m_wifi_init
  1205. @warning must be called after the initializations and before any connection request and can't be changed in run time,
  1206. */
  1207. sint8 m2m_wifi_set_power_profile(uint8 u8PwrMode)
  1208. {
  1209. sint8 ret = M2M_SUCCESS;
  1210. tstrM2mPwrMode strM2mPwrMode;
  1211. strM2mPwrMode.u8PwrMode = u8PwrMode;
  1212. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_POWER_PROFILE, (uint8*)&strM2mPwrMode,sizeof(tstrM2mPwrMode), NULL, 0, 0);
  1213. return ret;
  1214. }
  1215. /*!
  1216. @fn NMI_API sint8 m2m_wifi_set_tx_power(uint8 u8TxPwrLevel);
  1217. @brief set the TX power tenuM2mTxPwrLevel
  1218. @param [in] u8TxPwrLevel
  1219. change the TX power tenuM2mTxPwrLevel
  1220. @return The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
  1221. @sa tenuM2mTxPwrLevel
  1222. @pre m2m_wifi_init
  1223. @warning
  1224. */
  1225. sint8 m2m_wifi_set_tx_power(uint8 u8TxPwrLevel)
  1226. {
  1227. sint8 ret = M2M_SUCCESS;
  1228. tstrM2mTxPwrLevel strM2mTxPwrLevel;
  1229. strM2mTxPwrLevel.u8TxPwrLevel = u8TxPwrLevel;
  1230. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_TX_POWER, (uint8*)&strM2mTxPwrLevel,sizeof(tstrM2mTxPwrLevel), NULL, 0, 0);
  1231. return ret;
  1232. }
  1233. /*!
  1234. @fn NMI_API sint8 m2m_wifi_enable_firmware_logs(uint8 u8Enable);
  1235. @brief Enable or Disable logs in run time (Disable Firmware logs will
  1236. enhance the firmware start-up time and performance)
  1237. @param [in] u8Enable
  1238. Set 1 to enable the logs 0 for disable
  1239. @return The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
  1240. @sa __DISABLE_FIRMWARE_LOGS__ (build option to disable logs from initializations)
  1241. @pre m2m_wifi_init
  1242. @warning
  1243. */
  1244. sint8 m2m_wifi_enable_firmware_logs(uint8 u8Enable)
  1245. {
  1246. sint8 ret = M2M_SUCCESS;
  1247. tstrM2mEnableLogs strM2mEnableLogs;
  1248. strM2mEnableLogs.u8Enable = u8Enable;
  1249. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_ENABLE_LOGS, (uint8*)&strM2mEnableLogs,sizeof(tstrM2mEnableLogs), NULL, 0, 0);
  1250. return ret;
  1251. }
  1252. /*!
  1253. @fn NMI_API sint8 m2m_wifi_set_battery_voltage(uint16 u16BattVoltx100);
  1254. @brief Enable or Disable logs in run time (Disable Firmware logs will
  1255. enhance the firmware start-up time and performance)
  1256. @param [in] u16BattVoltx100
  1257. battery voltage multiplied by 100
  1258. @return The function SHALL return @ref M2M_SUCCESS for success and a negative value otherwise.
  1259. @sa __DISABLE_FIRMWARE_LOGS__ (build option to disable logs from initializations)
  1260. @pre m2m_wifi_init
  1261. @warning
  1262. */
  1263. sint8 m2m_wifi_set_battery_voltage(uint16 u16BattVoltx100)
  1264. {
  1265. sint8 ret = M2M_SUCCESS;
  1266. tstrM2mBatteryVoltage strM2mBattVol = {0};
  1267. strM2mBattVol.u16BattVolt = u16BattVoltx100;
  1268. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_BATTERY_VOLTAGE, (uint8*)&strM2mBattVol,sizeof(tstrM2mBatteryVoltage), NULL, 0, 0);
  1269. return ret;
  1270. }
  1271. /*!
  1272. @fn sint8 m2m_wifi_prng_get_random_bytes(uint8 * pu8PrngBuff,uint16 u16PrngSize)
  1273. @brief Get random bytes using the PRNG bytes.
  1274. @param [in] u16PrngSize
  1275. Size of the required random bytes to be generated.
  1276. @param [in] pu8PrngBuff
  1277. Pointer to user allocated buffer.
  1278. @return The function SHALL return M2M_SUCCESE for success and a negative value otherwise.
  1279. */
  1280. sint8 m2m_wifi_prng_get_random_bytes(uint8 * pu8PrngBuff,uint16 u16PrngSize)
  1281. {
  1282. sint8 ret = M2M_ERR_FAIL;
  1283. tstrPrng strRng = {0};
  1284. if((u16PrngSize < (M2M_BUFFER_MAX_SIZE - sizeof(tstrPrng)))&&(pu8PrngBuff != NULL))
  1285. {
  1286. strRng.u16PrngSize = u16PrngSize;
  1287. strRng.pu8RngBuff = pu8PrngBuff;
  1288. ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_GET_PRNG|M2M_REQ_DATA_PKT,(uint8 *)&strRng, sizeof(tstrPrng),NULL,0, 0);
  1289. }
  1290. else
  1291. {
  1292. M2M_ERR("PRNG Buffer exceeded maximum size %d or NULL Buffer\n",u16PrngSize);
  1293. }
  1294. return ret;
  1295. }
  1296. #ifdef ETH_MODE
  1297. /*!
  1298. @fn \
  1299. NMI_API sint8 m2m_wifi_enable_mac_mcast(uint8* pu8MulticastMacAddress, uint8 u8AddRemove)
  1300. @brief
  1301. Add MAC filter to receive Multicast packets.
  1302. @param [in] pu8MulticastMacAddress
  1303. Pointer to the MAC address.
  1304. @param [in] u8AddRemove
  1305. Flag to Add/Remove MAC address.
  1306. @return
  1307. The function SHALL return 0 for success and a negative value otherwise.
  1308. */
  1309. NMI_API sint8 m2m_wifi_enable_mac_mcast(uint8* pu8MulticastMacAddress, uint8 u8AddRemove)
  1310. {
  1311. sint8 s8ret = M2M_ERR_FAIL;
  1312. tstrM2MMulticastMac strMulticastMac;
  1313. if(pu8MulticastMacAddress != NULL )
  1314. {
  1315. strMulticastMac.u8AddRemove = u8AddRemove;
  1316. m2m_memcpy(strMulticastMac.au8macaddress,pu8MulticastMacAddress,M2M_MAC_ADDRES_LEN);
  1317. M2M_DBG("mac multicast: %x:%x:%x:%x:%x:%x\r\n",strMulticastMac.au8macaddress[0],strMulticastMac.au8macaddress[1],strMulticastMac.au8macaddress[2],strMulticastMac.au8macaddress[3],strMulticastMac.au8macaddress[4],strMulticastMac.au8macaddress[5]);
  1318. s8ret = hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_SET_MAC_MCAST, (uint8 *)&strMulticastMac,sizeof(tstrM2MMulticastMac),NULL,0,0);
  1319. }
  1320. return s8ret;
  1321. }
  1322. /*!
  1323. @fn \
  1324. NMI_API sint8 m2m_wifi_set_receive_buffer(void* pvBuffer,uint16 u16BufferLen);
  1325. @brief
  1326. set the ethernet receive buffer, should be called in the receive call back.
  1327. @param [in] pvBuffer
  1328. Pointer to the ethernet receive buffer.
  1329. @param [in] u16BufferLen
  1330. Length of the buffer.
  1331. @return
  1332. The function SHALL return 0 for success and a negative value otherwise.
  1333. */
  1334. NMI_API sint8 m2m_wifi_set_receive_buffer(void* pvBuffer,uint16 u16BufferLen)
  1335. {
  1336. sint8 s8ret = M2M_SUCCESS;
  1337. if(pvBuffer != NULL)
  1338. {
  1339. gau8ethRcvBuf = pvBuffer;
  1340. gu16ethRcvBufSize= u16BufferLen;
  1341. }
  1342. else
  1343. {
  1344. s8ret = M2M_ERR_FAIL;
  1345. M2M_ERR("Buffer NULL pointer\r\n");
  1346. }
  1347. return s8ret;
  1348. }
  1349. #endif
  1350. /*!
  1351. @fn \
  1352. NMI_API sint8 m2m_wifi_ble_api_send(const uint8* const msg, const uint32 len);
  1353. @brief
  1354. Send an encapsulated Atmel BLE API message
  1355. @param [in] msg
  1356. Pointer to the Atmel BLE API message raw bytes
  1357. @param [in] len
  1358. Length of the msg
  1359. @return
  1360. The function SHALL return 0 for success and a negative value otherwise.
  1361. */
  1362. NMI_API sint8 m2m_wifi_ble_api_send(uint8* msg, uint32 len)
  1363. {
  1364. tstrM2mBleApiMsg bleTx;
  1365. bleTx.u16Len = len;
  1366. return hif_send(M2M_REQ_GROUP_WIFI, M2M_WIFI_REQ_BLE_API_SEND | M2M_REQ_DATA_PKT,
  1367. (uint8*)&bleTx, sizeof(tstrM2mBleApiMsg), msg, len, sizeof(tstrM2mBleApiMsg));
  1368. }