1 /**
2 *
3 * \file
4 *
5 * \brief This module contains M2M host interface APIs implementation.
6 *
7 * Copyright (c) 2016-2017 Atmel Corporation. All rights reserved.
8 *
9 * \asf_license_start
10 *
11 * \page License
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright notice,
20 * this list of conditions and the following disclaimer in the documentation
21 * and/or other materials provided with the distribution.
22 *
23 * 3. The name of Atmel may not be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
27 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
29 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 * \asf_license_stop
39 *
40 */
41
42 #include "common/include/nm_common.h"
43 #include "driver/source/nmbus.h"
44 #include "bsp/include/nm_bsp.h"
45 #include "m2m_hif.h"
46 #include "driver/include/m2m_types.h"
47 #include "driver/source/nmasic.h"
48 #include "driver/include/m2m_periph.h"
49
50 #if (defined NM_EDGE_INTERRUPT)&&(defined NM_LEVEL_INTERRUPT)
51 #error "only one type of interrupt NM_EDGE_INTERRUPT,NM_LEVEL_INTERRUPT"
52 #endif
53
54 #if !((defined NM_EDGE_INTERRUPT)||(defined NM_LEVEL_INTERRUPT))
55 #error "define interrupt type NM_EDGE_INTERRUPT,NM_LEVEL_INTERRUPT"
56 #endif
57
58 #ifndef CORTUS_APP
59 #define NMI_AHB_DATA_MEM_BASE 0x30000
60 #define NMI_AHB_SHARE_MEM_BASE 0xd0000
61
62 #define WIFI_HOST_RCV_CTRL_0 (0x1070)
63 #define WIFI_HOST_RCV_CTRL_1 (0x1084)
64 #define WIFI_HOST_RCV_CTRL_2 (0x1078)
65 #define WIFI_HOST_RCV_CTRL_3 (0x106c)
66 #define WIFI_HOST_RCV_CTRL_4 (0x150400)
67 #define WIFI_HOST_RCV_CTRL_5 (0x1088)
68
69 typedef struct {
70 uint8 u8ChipMode;
71 uint8 u8ChipSleep;
72 uint8 u8HifRXDone;
73 uint8 u8Interrupt;
74 uint32 u32RxAddr;
75 uint32 u32RxSize;
76 tpfHifCallBack pfWifiCb;
77 tpfHifCallBack pfIpCb;
78 tpfHifCallBack pfOtaCb;
79 tpfHifCallBack pfSigmaCb;
80 tpfHifCallBack pfHifCb;
81 tpfHifCallBack pfCryptoCb;
82 tpfHifCallBack pfSslCb;
83 }tstrHifContext;
84
85 volatile tstrHifContext gstrHifCxt;
86
isr(void)87 static void isr(void)
88 {
89 gstrHifCxt.u8Interrupt++;
90 #ifdef NM_LEVEL_INTERRUPT
91 nm_bsp_interrupt_ctrl(0);
92 #endif
93 }
hif_set_rx_done(void)94 static sint8 hif_set_rx_done(void)
95 {
96 uint32 reg;
97 sint8 ret = M2M_SUCCESS;
98
99 gstrHifCxt.u8HifRXDone = 0;
100 #ifdef NM_EDGE_INTERRUPT
101 nm_bsp_interrupt_ctrl(1);
102 #endif
103 ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0,®);
104 if(ret != M2M_SUCCESS)goto ERR1;
105 /* Set RX Done */
106 reg |= NBIT1;
107 ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg);
108 if(ret != M2M_SUCCESS)goto ERR1;
109 #ifdef NM_LEVEL_INTERRUPT
110 nm_bsp_interrupt_ctrl(1);
111 #endif
112 ERR1:
113 return ret;
114
115 }
116 /**
117 * @fn static void m2m_hif_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
118 * @brief WiFi call back function
119 * @param [in] u8OpCode
120 * HIF Opcode type.
121 * @param [in] u16DataSize
122 * HIF data length.
123 * @param [in] u32Addr
124 * HIF address.
125 * @param [in] grp
126 * HIF group type.
127 * @author
128 * @date
129 * @version 1.0
130 */
m2m_hif_cb(uint8 u8OpCode,uint16 u16DataSize,uint32 u32Addr)131 static void m2m_hif_cb(uint8 u8OpCode, uint16 u16DataSize, uint32 u32Addr)
132 {
133
134
135 }
136 /**
137 * @fn NMI_API sint8 hif_chip_wake(void);
138 * @brief To Wakeup the chip.
139 * @return The function shall return ZERO for successful operation and a negative value otherwise.
140 */
141
hif_chip_wake(void)142 sint8 hif_chip_wake(void)
143 {
144 sint8 ret = M2M_SUCCESS;
145 if(gstrHifCxt.u8HifRXDone)
146 {
147 /*chip already wake for the rx not done no need to send wake request*/
148 return ret;
149 }
150 if(gstrHifCxt.u8ChipSleep == 0)
151 {
152 if(gstrHifCxt.u8ChipMode != M2M_NO_PS)
153 {
154 ret = chip_wake();
155 if(ret != M2M_SUCCESS)goto ERR1;
156 }
157 else
158 {
159 }
160 }
161 gstrHifCxt.u8ChipSleep++;
162 ERR1:
163 return ret;
164 }
165 /*!
166 @fn \
167 NMI_API void hif_set_sleep_mode(uint8 u8Pstype);
168
169 @brief
170 Set the sleep mode of the HIF layer.
171
172 @param [in] u8Pstype
173 Sleep mode.
174
175 @return
176 The function SHALL return 0 for success and a negative value otherwise.
177 */
178
hif_set_sleep_mode(uint8 u8Pstype)179 void hif_set_sleep_mode(uint8 u8Pstype)
180 {
181 gstrHifCxt.u8ChipMode = u8Pstype;
182 }
183 /*!
184 @fn \
185 NMI_API uint8 hif_get_sleep_mode(void);
186
187 @brief
188 Get the sleep mode of the HIF layer.
189
190 @return
191 The function SHALL return the sleep mode of the HIF layer.
192 */
193
hif_get_sleep_mode(void)194 uint8 hif_get_sleep_mode(void)
195 {
196 return gstrHifCxt.u8ChipMode;
197 }
198
199 /**
200 * @fn NMI_API sint8 hif_chip_sleep_sc(void);
201 * @brief To clear the chip sleep but keep the chip sleep
202 * @return The function shall return ZERO for successful operation and a negative value otherwise.
203 */
204
hif_chip_sleep_sc(void)205 sint8 hif_chip_sleep_sc(void)
206 {
207 if(gstrHifCxt.u8ChipSleep >= 1)
208 {
209 gstrHifCxt.u8ChipSleep--;
210 }
211 return M2M_SUCCESS;
212 }
213 /**
214 * @fn NMI_API sint8 hif_chip_sleep(void);
215 * @brief To make the chip sleep.
216 * @return The function shall return ZERO for successful operation and a negative value otherwise.
217 */
218
hif_chip_sleep(void)219 sint8 hif_chip_sleep(void)
220 {
221 sint8 ret = M2M_SUCCESS;
222
223 if(gstrHifCxt.u8ChipSleep >= 1)
224 {
225 gstrHifCxt.u8ChipSleep--;
226 }
227
228 if(gstrHifCxt.u8ChipSleep == 0)
229 {
230 if(gstrHifCxt.u8ChipMode != M2M_NO_PS)
231 {
232 ret = chip_sleep();
233 if(ret != M2M_SUCCESS)goto ERR1;
234
235 }
236 else
237 {
238 }
239 }
240 ERR1:
241 return ret;
242 }
243 /**
244 * @fn NMI_API sint8 hif_init(void * arg);
245 * @brief To initialize HIF layer.
246 * @param [in] arg
247 * Pointer to the arguments.
248 * @return The function shall return ZERO for successful operation and a negative value otherwise.
249 */
250
hif_init(void * arg)251 sint8 hif_init(void * arg)
252 {
253 m2m_memset((uint8*)&gstrHifCxt,0,sizeof(tstrHifContext));
254 nm_bsp_register_isr(isr);
255 hif_register_cb(M2M_REQ_GROUP_HIF,m2m_hif_cb);
256 return M2M_SUCCESS;
257 }
258 /**
259 * @fn NMI_API sint8 hif_deinit(void * arg);
260 * @brief To De-initialize HIF layer.
261 * @param [in] arg
262 * Pointer to the arguments.
263 * @return The function shall return ZERO for successful operation and a negative value otherwise.
264 */
hif_deinit(void * arg)265 sint8 hif_deinit(void * arg)
266 {
267 sint8 ret = M2M_SUCCESS;
268 ret = hif_chip_wake();
269 m2m_memset((uint8*)&gstrHifCxt,0,sizeof(tstrHifContext));
270 return ret;
271 }
272 /**
273 * @fn NMI_API sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
274 uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset)
275 * @brief Send packet using host interface.
276
277 * @param [in] u8Gid
278 * Group ID.
279 * @param [in] u8Opcode
280 * Operation ID.
281 * @param [in] pu8CtrlBuf
282 * Pointer to the Control buffer.
283 * @param [in] u16CtrlBufSize
284 Control buffer size.
285 * @param [in] u16DataOffset
286 Packet Data offset.
287 * @param [in] pu8DataBuf
288 * Packet buffer Allocated by the caller.
289 * @param [in] u16DataSize
290 Packet buffer size (including the HIF header).
291 * @return The function shall return ZERO for successful operation and a negative value otherwise.
292 */
293
hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 * pu8CtrlBuf,uint16 u16CtrlBufSize,uint8 * pu8DataBuf,uint16 u16DataSize,uint16 u16DataOffset)294 sint8 hif_send(uint8 u8Gid,uint8 u8Opcode,uint8 *pu8CtrlBuf,uint16 u16CtrlBufSize,
295 uint8 *pu8DataBuf,uint16 u16DataSize, uint16 u16DataOffset)
296 {
297 sint8 ret = M2M_ERR_SEND;
298 volatile tstrHifHdr strHif;
299
300 strHif.u8Opcode = u8Opcode&(~NBIT7);
301 strHif.u8Gid = u8Gid;
302 strHif.u16Length = M2M_HIF_HDR_OFFSET;
303 if(pu8DataBuf != NULL)
304 {
305 strHif.u16Length += u16DataOffset + u16DataSize;
306 }
307 else
308 {
309 strHif.u16Length += u16CtrlBufSize;
310 }
311 ret = hif_chip_wake();
312 if(ret == M2M_SUCCESS)
313 {
314 volatile uint32 reg, dma_addr = 0;
315 volatile uint16 cnt = 0;
316 //#define OPTIMIZE_BUS
317 /*please define in firmware also*/
318 #ifndef OPTIMIZE_BUS
319 reg = 0UL;
320 reg |= (uint32)u8Gid;
321 reg |= ((uint32)u8Opcode<<8);
322 reg |= ((uint32)strHif.u16Length<<16);
323 ret = nm_write_reg(NMI_STATE_REG,reg);
324 if(M2M_SUCCESS != ret) goto ERR1;
325
326 reg = 0UL;
327 reg |= NBIT1;
328 ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
329 if(M2M_SUCCESS != ret) goto ERR1;
330 #else
331 reg = 0UL;
332 reg |= NBIT1;
333 reg |= ((u8Opcode & NBIT7) ? (NBIT2):(0)); /*Data = 1 or config*/
334 reg |= (u8Gid == M2M_REQ_GROUP_IP) ? (NBIT3):(0); /*IP = 1 or non IP*/
335 reg |= ((uint32)strHif.u16Length << 4); /*length of pkt max = 4096*/
336 ret = nm_write_reg(WIFI_HOST_RCV_CTRL_2, reg);
337 if(M2M_SUCCESS != ret) goto ERR1;
338 #endif
339 dma_addr = 0;
340
341 for(cnt = 0; cnt < 1000; cnt ++)
342 {
343 ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_2,(uint32 *)®);
344 if(ret != M2M_SUCCESS) break;
345 /*
346 * If it takes too long to get a response, the slow down to
347 * avoid back-to-back register read operations.
348 */
349 if(cnt >= 500) {
350 if(cnt < 501) {
351 M2M_INFO("Slowing down...\n");
352 }
353 nm_bsp_sleep(1);
354 }
355 if (!(reg & NBIT1))
356 {
357 ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_4,(uint32 *)&dma_addr);
358 if(ret != M2M_SUCCESS) {
359 /*in case of read error clear the DMA address and return error*/
360 dma_addr = 0;
361 goto ERR1;
362 }
363 /*in case of success break */
364 break;
365 }
366 }
367
368 if (dma_addr != 0)
369 {
370 volatile uint32 u32CurrAddr;
371 u32CurrAddr = dma_addr;
372 strHif.u16Length=NM_BSP_B_L_16(strHif.u16Length);
373 ret = nm_write_block(u32CurrAddr, (uint8*)&strHif, M2M_HIF_HDR_OFFSET);
374 if(M2M_SUCCESS != ret) goto ERR1;
375 u32CurrAddr += M2M_HIF_HDR_OFFSET;
376 if(pu8CtrlBuf != NULL)
377 {
378 ret = nm_write_block(u32CurrAddr, pu8CtrlBuf, u16CtrlBufSize);
379 if(M2M_SUCCESS != ret) goto ERR1;
380 u32CurrAddr += u16CtrlBufSize;
381 }
382 if(pu8DataBuf != NULL)
383 {
384 u32CurrAddr += (u16DataOffset - u16CtrlBufSize);
385 ret = nm_write_block(u32CurrAddr, pu8DataBuf, u16DataSize);
386 if(M2M_SUCCESS != ret) goto ERR1;
387 u32CurrAddr += u16DataSize;
388 }
389
390 reg = dma_addr << 2;
391 reg |= NBIT1;
392 ret = nm_write_reg(WIFI_HOST_RCV_CTRL_3, reg);
393 if(M2M_SUCCESS != ret) goto ERR1;
394 }
395 else
396 {
397 ret = hif_chip_sleep();
398 M2M_DBG("Failed to alloc rx size %d\r",ret);
399 ret = M2M_ERR_MEM_ALLOC;
400 goto ERR2;
401 }
402
403 }
404 else
405 {
406 M2M_ERR("(HIF)Fail to wakup the chip\n");
407 goto ERR2;
408 }
409 /*actual sleep ret = M2M_SUCCESS*/
410 ret = hif_chip_sleep();
411 return ret;
412 ERR1:
413 /*reset the count but no actual sleep as it already bus error*/
414 hif_chip_sleep_sc();
415 ERR2:
416 /*logical error*/
417 return ret;
418 }
419 /**
420 * @fn hif_isr
421 * @brief Host interface interrupt service routine
422 * @author M. Abdelmawla
423 * @date 15 July 2012
424 * @return 1 in case of interrupt received else 0 will be returned
425 * @version 1.0
426 */
hif_isr(void)427 static sint8 hif_isr(void)
428 {
429 sint8 ret = M2M_SUCCESS;
430 uint32 reg;
431 volatile tstrHifHdr strHif;
432
433 ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_0, ®);
434 if(M2M_SUCCESS == ret)
435 {
436 if(reg & 0x1) /* New interrupt has been received */
437 {
438 uint16 size;
439
440 nm_bsp_interrupt_ctrl(0);
441 /*Clearing RX interrupt*/
442 reg &= ~NBIT0;
443 ret = nm_write_reg(WIFI_HOST_RCV_CTRL_0,reg);
444 if(ret != M2M_SUCCESS)goto ERR1;
445 gstrHifCxt.u8HifRXDone = 1;
446 size = (uint16)((reg >> 2) & 0xfff);
447 if (size > 0) {
448 uint32 address = 0;
449 /**
450 start bus transfer
451 **/
452 ret = nm_read_reg_with_ret(WIFI_HOST_RCV_CTRL_1, &address);
453 if(M2M_SUCCESS != ret)
454 {
455 M2M_ERR("(hif) WIFI_HOST_RCV_CTRL_1 bus fail\n");
456 nm_bsp_interrupt_ctrl(1);
457 goto ERR1;
458 }
459 gstrHifCxt.u32RxAddr = address;
460 gstrHifCxt.u32RxSize = size;
461 ret = nm_read_block(address, (uint8*)&strHif, sizeof(tstrHifHdr));
462 strHif.u16Length = NM_BSP_B_L_16(strHif.u16Length);
463 if(M2M_SUCCESS != ret)
464 {
465 M2M_ERR("(hif) address bus fail\n");
466 nm_bsp_interrupt_ctrl(1);
467 goto ERR1;
468 }
469 if(strHif.u16Length != size)
470 {
471 if((size - strHif.u16Length) > 4)
472 {
473 M2M_ERR("(hif) Corrupted packet Size = %u <L = %u, G = %u, OP = %02X>\n",
474 size, strHif.u16Length, strHif.u8Gid, strHif.u8Opcode);
475 nm_bsp_interrupt_ctrl(1);
476 ret = M2M_ERR_BUS_FAIL;
477 goto ERR1;
478 }
479 }
480
481 if(M2M_REQ_GROUP_WIFI == strHif.u8Gid)
482 {
483 if(gstrHifCxt.pfWifiCb)
484 gstrHifCxt.pfWifiCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
485 else
486 M2M_ERR("WIFI callback is not registered\n");
487
488 }
489 else if(M2M_REQ_GROUP_IP == strHif.u8Gid)
490 {
491 if(gstrHifCxt.pfIpCb)
492 gstrHifCxt.pfIpCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
493 else
494 M2M_ERR("Scoket callback is not registered\n");
495
496 }
497 else if(M2M_REQ_GROUP_OTA == strHif.u8Gid)
498 {
499 if(gstrHifCxt.pfOtaCb)
500 gstrHifCxt.pfOtaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
501 else
502 M2M_ERR("Ota callback is not registered\n");
503
504 }
505 else if(M2M_REQ_GROUP_CRYPTO == strHif.u8Gid)
506 {
507 if(gstrHifCxt.pfCryptoCb)
508 gstrHifCxt.pfCryptoCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
509
510 else
511 M2M_ERR("Crypto callback is not registered\n");
512 }
513 else if(M2M_REQ_GROUP_SIGMA == strHif.u8Gid)
514 {
515 if(gstrHifCxt.pfSigmaCb)
516 gstrHifCxt.pfSigmaCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
517 else
518 M2M_ERR("Sigma callback is not registered\n");
519 }
520 else if(M2M_REQ_GROUP_SSL == strHif.u8Gid)
521 {
522 if(gstrHifCxt.pfSslCb)
523 gstrHifCxt.pfSslCb(strHif.u8Opcode,strHif.u16Length - M2M_HIF_HDR_OFFSET, address + M2M_HIF_HDR_OFFSET);
524 }
525 else
526 {
527 M2M_ERR("(hif) invalid group ID\n");
528 ret = M2M_ERR_BUS_FAIL;
529 goto ERR1;
530 }
531 if(gstrHifCxt.u8HifRXDone)
532 {
533 M2M_ERR("(hif) host app didn't set RX Done <%u><%X>\n", strHif.u8Gid, strHif.u8Opcode);
534 ret = hif_set_rx_done();
535 if(ret != M2M_SUCCESS) goto ERR1;
536 }
537 }
538 else
539 {
540 M2M_ERR("(hif) Wrong Size\n");
541 ret = M2M_ERR_RCV;
542 goto ERR1;
543 }
544 }
545 else
546 {
547 #ifndef WIN32
548 M2M_ERR("(hif) False interrupt %lx",reg);
549 ret = M2M_ERR_FAIL;
550 goto ERR1;
551 #else
552 #endif
553 }
554 }
555 else
556 {
557 M2M_ERR("(hif) Fail to Read interrupt reg\n");
558 goto ERR1;
559 }
560
561 ERR1:
562 return ret;
563 }
564
565 /**
566 * @fn hif_handle_isr(void)
567 * @brief Handle interrupt received from NMC1500 firmware.
568 * @return The function SHALL return 0 for success and a negative value otherwise.
569 */
570
hif_handle_isr(void)571 sint8 hif_handle_isr(void)
572 {
573 sint8 ret = M2M_SUCCESS;
574 while (gstrHifCxt.u8Interrupt) {
575 /*must be at that place because of the race of interrupt increment and that decrement*/
576 /*when the interrupt enabled*/
577 gstrHifCxt.u8Interrupt--;
578 while(1)
579 {
580 ret = hif_isr();
581 if(ret == M2M_SUCCESS) {
582 /*we will try forever untill we get that interrupt*/
583 /*Fail return errors here due to bus errors (reading expected values)*/
584 break;
585 } else {
586 M2M_ERR("(HIF) Fail to handle interrupt %d try Again..\n",ret);
587 }
588 }
589 }
590
591 return ret;
592 }
593 /*
594 * @fn hif_receive
595 * @brief Host interface interrupt serviece routine
596 * @param [in] u32Addr
597 * Receive start address
598 * @param [out] pu8Buf
599 * Pointer to receive buffer. Allocated by the caller
600 * @param [in] u16Sz
601 * Receive buffer size
602 * @param [in] isDone
603 * If you don't need any more packets send True otherwise send false
604 * @return The function shall return ZERO for successful operation and a negative value otherwise.
605 */
hif_receive(uint32 u32Addr,uint8 * pu8Buf,uint16 u16Sz,uint8 isDone)606 sint8 hif_receive(uint32 u32Addr, uint8 *pu8Buf, uint16 u16Sz, uint8 isDone)
607 {
608 sint8 ret = M2M_SUCCESS;
609 if((u32Addr == 0)||(pu8Buf == NULL) || (u16Sz == 0))
610 {
611 if(isDone)
612 {
613 /* set RX done */
614 ret = hif_set_rx_done();
615 }
616 else
617 {
618 ret = M2M_ERR_FAIL;
619 M2M_ERR(" hif_receive: Invalid argument\n");
620 }
621 goto ERR1;
622 }
623
624 if(u16Sz > gstrHifCxt.u32RxSize)
625 {
626 ret = M2M_ERR_FAIL;
627 M2M_ERR("APP Requested Size is larger than the recived buffer size <%u><%lu>\n",u16Sz, gstrHifCxt.u32RxSize);
628 goto ERR1;
629 }
630 if((u32Addr < gstrHifCxt.u32RxAddr)||((u32Addr + u16Sz)>(gstrHifCxt.u32RxAddr + gstrHifCxt.u32RxSize)))
631 {
632 ret = M2M_ERR_FAIL;
633 M2M_ERR("APP Requested Address beyond the recived buffer address and length\n");
634 goto ERR1;
635 }
636
637 /* Receive the payload */
638 ret = nm_read_block(u32Addr, pu8Buf, u16Sz);
639 if(ret != M2M_SUCCESS)goto ERR1;
640
641 /* check if this is the last packet */
642 if((((gstrHifCxt.u32RxAddr + gstrHifCxt.u32RxSize) - (u32Addr + u16Sz)) <= 0) || isDone)
643 {
644 /* set RX done */
645 ret = hif_set_rx_done();
646 }
647
648 ERR1:
649 return ret;
650 }
651
652 /**
653 * @fn hif_register_cb
654 * @brief To set Callback function for every compantent Component
655 * @param [in] u8Grp
656 * Group to which the Callback function should be set.
657 * @param [in] fn
658 * function to be set
659 * @return The function shall return ZERO for successful operation and a negative value otherwise.
660 */
661
hif_register_cb(uint8 u8Grp,tpfHifCallBack fn)662 sint8 hif_register_cb(uint8 u8Grp,tpfHifCallBack fn)
663 {
664 sint8 ret = M2M_SUCCESS;
665 switch(u8Grp)
666 {
667 case M2M_REQ_GROUP_IP:
668 gstrHifCxt.pfIpCb = fn;
669 break;
670 case M2M_REQ_GROUP_WIFI:
671 gstrHifCxt.pfWifiCb = fn;
672 break;
673 case M2M_REQ_GROUP_OTA:
674 gstrHifCxt.pfOtaCb = fn;
675 break;
676 case M2M_REQ_GROUP_HIF:
677 gstrHifCxt.pfHifCb = fn;
678 break;
679 case M2M_REQ_GROUP_CRYPTO:
680 gstrHifCxt.pfCryptoCb = fn;
681 break;
682 case M2M_REQ_GROUP_SIGMA:
683 gstrHifCxt.pfSigmaCb = fn;
684 break;
685 case M2M_REQ_GROUP_SSL:
686 gstrHifCxt.pfSslCb = fn;
687 break;
688 default:
689 M2M_ERR("GRp ? %d\n",u8Grp);
690 ret = M2M_ERR_FAIL;
691 break;
692 }
693 return ret;
694 }
695
696 #endif
697