iotivity 0.9.0
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SampleApp / arduino / Reference_Thing / src / bleLib.cpp
1 /*
2  * blsLib.cpp
3  *
4  *  Created on: 2014. 11. 5.
5  *      Author: eunseok
6  */
7
8 #include "bleLib.h"
9 #include <stdarg.h>
10
11 #define ARDUINO                 1
12 //#define __INTERNAL_DEBUG__            1
13
14
15 #define LIMIT_COUNT                     100
16 #define DUMMY_SIZE                      30
17 #define DEBUG_SIZE                      DUMMY_SIZE
18 #if (ARDUINO != 0)
19 #define SERIAL_SIZE                     100
20 #endif
21
22 #define BLE             Serial2
23
24 bool isConnected = false;
25 int SerialCnt=0;
26 int BLECnt=0;
27 char SelfMaxaddr[19] = {0,};
28
29 char debugD[DEBUG_SIZE]={0,};
30
31 #if (ARDUINO != 0)
32 char SerialData[SERIAL_SIZE]={0,};
33 char BLEData[SERIAL_SIZE]={0,};
34 #endif
35
36 // baudRate이 115200이면, 주의해야한다.
37 // Arduino Chip은 16bit Process 이므로 int형의 사이즈가 4byte형 signed int이다.
38 void Cble::init(long baudRate, int ble_mode, char* SelfMaxAddr)
39 {
40         debug_printf("BLE shiled is initialed.-\r\n");
41
42         if(SelfMaxAddr == NULL && ble_mode != BLE_NOCHANGE )
43         {
44                 debug_printf("Error : Insert Maxaddress of Arduino BLE shiled.\r\n");
45                 exit(-1);
46         }
47         sprintf(SelfMaxaddr, "%s",SelfMaxAddr);
48
49         BLE.begin(baudRate);
50         BLE.setTimeout(1);
51         delay(1000);
52
53         memset(debugD,0,DEBUG_SIZE);
54
55         if( ble_mode != BLE_NOCHANGE )
56         {
57                 while( IsSelfArduino() == false )
58                         this->pollingDisconnect();
59         }
60
61         if( ble_mode == BLE_MASTER )
62         {
63                 pollingRequest("AT+ROLE1", debugD, 8);
64                 memset(debugD, 0, DEBUG_SIZE);
65                 delay(150);
66                 pollingRequest("AT+MODE0", debugD, 8);
67                 memset(debugD, 0, DEBUG_SIZE);
68                 delay(150);
69                 pollingRequest("AT+NOTI0", debugD, 8);
70                 memset(debugD, 0, DEBUG_SIZE);
71         }
72         else if ( ble_mode == BLE_SLAVER )
73         {
74                 pollingRequest("AT+ROLE0", debugD, 8);
75                 memset(debugD, 0, DEBUG_SIZE);
76                 delay(150);
77                 pollingRequest("AT+MODE2", debugD, 8);
78                 memset(debugD, 0, DEBUG_SIZE);
79                 delay(150);
80                 pollingRequest("AT+NOTI0", debugD, 8);
81                 memset(debugD, 0, DEBUG_SIZE);
82         }
83
84         if( ble_mode != BLE_NOCHANGE )
85         {
86                 while( IsSelfArduino() == false )
87                         this->pollingDisconnect();
88         }
89
90         delay(250);
91 }
92
93 void Cble::StatusRead( void )
94 {
95         debug_printf("StatusRead function called.\r\n");
96
97         pollingRequest("AT+ROLE?", debugD, 9);
98         memset(debugD, 0, DEBUG_SIZE);
99         delay(150);
100         pollingRequest("AT+MODE?", debugD, 8);
101         memset(debugD, 0, DEBUG_SIZE);
102         delay(150);
103         pollingRequest("AT+IMME?", debugD, 9);
104         memset(debugD, 0, DEBUG_SIZE);
105         delay(150);
106         pollingRequest("AT+TYPE?", debugD, 8);
107         memset(debugD, 0, DEBUG_SIZE);
108         delay(150);
109         pollingRequest("AT+POWE?", debugD, 8);
110         memset(debugD, 0, DEBUG_SIZE);
111         delay(150);
112         pollingRequest("AT+NOTI?", debugD, 8);
113         memset(debugD, 0, DEBUG_SIZE);
114         delay(150);
115         pollingRequest("AT+PIO1?", debugD, 8);
116         memset(debugD, 0, DEBUG_SIZE);
117         delay(150);
118 }
119
120 bool Cble::IsConnected( void )
121 {
122         return isConnected;
123 }
124
125 bool Cble::IsSelfArduino( void )
126 {
127 #ifdef __INTERNAL_DEBUG__
128         debug_printf("IsSelfArduino is called.\r\n");
129 #endif
130         int length=mustHaveRequest("AT+ADDR?", debugD, 20);
131
132         if( strstr(debugD, SelfMaxaddr) )
133         {
134                 isConnected = false;
135                 memset(debugD,0,length);
136                 return true;
137         }
138         else
139         {
140                 isConnected = true;
141                 memset(debugD,0,length);
142                 return false;
143         }
144 }
145
146 bool Cble::pollingConnect( const char* maxAddr )
147 {
148 #ifdef __INTERNAL_DEBUG__
149         debug_printf("pollingConnect is called.\r\n");
150 #endif
151
152 #define CONNECT_SIZE            20
153
154         char cmd[CONNECT_SIZE]= {0,};
155
156         // is Connected Address ?
157         pollingRequest("AT+ADDR?", debugD, 20);
158         if( strstr(debugD, maxAddr) )
159         {
160                 isConnected = true;
161                 memset(debugD,0,DEBUG_SIZE);
162                 return isConnected;
163         }
164         memset(debugD,0,DEBUG_SIZE);
165
166         // Try Connection.
167         sprintf(cmd, "AT+CON%s",maxAddr);
168         if( pollingRequest(cmd, debugD, 8) == false )
169         {
170                 debug_printf("Error : %s command is failed.\r\n",cmd );
171                 memset(debugD,0,DEBUG_SIZE);
172                 pollingDisconnect();
173                 return false;
174         }
175         else if( strstr(debugD,"OK+CONNA") )
176         {
177                 isConnected = true;
178                 memset(debugD,0,DEBUG_SIZE);
179         }
180         else
181         {
182                 memset(debugD,0,DEBUG_SIZE);
183                 pollingDisconnect();
184                 return false;
185         }
186
187         // Confirm Connected Address.
188         pollingRequest("AT+ADDR?", debugD, 20);
189
190         if( strstr(debugD, maxAddr) == 0 )
191         {
192                 isConnected = false;
193                 if ( strstr(debugD, "OK+CONNF") )
194                 {
195                         memset(debugD,0,DEBUG_SIZE);
196                         streamDummy(debugD, 8);
197                 }
198         }
199         memset(debugD,0,DEBUG_SIZE);
200         delay(5);
201
202         return isConnected;
203
204 #undef CONNECT_SIZE
205 }
206
207
208 #define  CMD_DISCONNECT         "(CMD_DISCON)"
209 void Cble::pollingDisconnect( void )
210 {
211 #ifdef __INTERNAL_DEBUG__
212         debug_printf("pollingDisconnect is called.\r\n");
213 #endif
214         int length=0;
215 #if (ARDUINO == 0)
216         pollingRequest("\r\n" CMD_DISCONNECT "\r\n", NULL, NULL);
217         delay(5);
218
219         length=mustHaveRequest("AT", debugD, 2);
220         if( strstr(debugD,"OK") )
221                 isConnected = false;
222
223         memset(debugD,0,length);
224 #else
225         if( BLE.available() )
226         {
227                 if( BLE.findUntil(CMD_DISCONNECT, "\r\n") == true )
228                 {
229                         debug_printf("pollingDisconnect : Detected %s command.\r\n", CMD_DISCONNECT);
230
231                         do {
232                                 debug_printf("pollingDisconnect : Send AT message.\r\n");
233                                 if( length )
234                                         memset(debugD, 0, length);
235
236                                 length=mustHaveRequest("AT", debugD, 2);
237                         }while( strstr(debugD,"OK") == NULL );
238
239                         debug_printf("pollingDisconnect() is Success.\r\n");
240                         memset(debugD, 0, length);
241                 }
242         }
243 #endif
244
245         delay(5);
246 }
247
248 int Cble::pollingGetRSSI( void )
249 {
250 #define RSSI_SIZE               11
251 #define RSSI_POS                7
252
253         long time_cnt=0;
254         char c=0;
255         char index=0;
256         char rssi_res[RSSI_SIZE] = {0,};
257
258         streamDummy(NULL, NULL);
259
260         if( isConnected == true )
261         {
262                 BLE.write("AT+RSSI?");
263                 BLE.flush();
264                 delay(5);
265
266                 while(1)
267                 {
268                         if ( BLE.available() )
269                                 c = (char)BLE.read();
270                         else
271                         {
272                                 c = 0;
273                                 time_cnt++;
274                         }
275
276                         if( c )
277                         {
278                                 rssi_res[index] = c;
279                                 index++;
280                                 if( index == RSSI_SIZE-1 )
281                                 {
282                                         rssi_res[index] = '\0';
283                                         goto RESULT;
284                                 }
285                         }
286
287                         if( time_cnt == 0xFFFFF )
288                         {
289                                 debug_printf("Error : Time Out GetRSSI().\r\n");
290                                 return BLE_NODATA;
291                         }
292
293                 }
294
295         RESULT :
296 #ifdef __INTERNAL_DEBUG__
297                 debug_printf("res= %s \r\n",rssi_res);
298 #endif
299                 char* Srssi = &(rssi_res[RSSI_POS]);
300                 int rssi = atoi(Srssi);
301
302                 return rssi;
303         }
304
305         return BLE_DISCON;
306
307 #undef RSSI_POS
308 #undef RSSI_SIZE
309 }
310
311 int Cble::mustHaveRequest(const char* request, char* data, int dataLen)
312 {
313         int cnt=0;
314         int length=0;
315         int required_length = dataLen;
316         char* data_index = data;
317
318         BLE.write(request);
319         BLE.flush();
320         delay(150);
321
322 READ_STREAM :
323         while( (length=BLE.readBytes(data_index, required_length)) == 0 )
324         {
325                 cnt++;
326                 delay(10);
327
328                 if ( cnt >= LIMIT_COUNT/10 )
329                 {
330 #ifdef __INTERNAL_DEBUG__
331                         debug_printf("=====> Retry Request command Send. <=========\r\n");
332 #endif
333                         cnt = 0;
334                         BLE.write(request);
335                         BLE.flush();
336
337                         required_length = dataLen;
338                         data_index = data;
339                         length = 0;
340                         delay(50);
341                 }
342         }
343
344         required_length -= length;
345         if( required_length != 0 )
346         {
347                 data_index = data_index + length;
348                 length = 0;
349                 goto READ_STREAM;
350         }
351
352 #ifdef __INTERNAL_DEBUG__
353         debug_printf("[ %s ] %s\r\n\r\n", request, data);
354 #endif
355         return dataLen;
356 }
357
358 bool Cble::pollingRequest(const char* request, char* data, int dataLen)
359 {
360         int cnt=0;
361         int length=0;
362         int required_length = dataLen;
363         char* data_index = data;
364
365         BLE.write(request);
366         BLE.flush();
367
368         if( data_index )
369         {
370                 delay(250);
371
372 READ_STREAM :
373                 while( (length=BLE.readBytes(data_index, required_length)) == 0 )
374                 {
375                         cnt++;
376                         if ( cnt >= LIMIT_COUNT )
377                         {
378                                 debug_printf("[ %s ] TimeOut : No data.\r\n\r\n", request);
379                                 return false;
380                         }
381                 }
382
383                 required_length -= length;
384                 if( required_length != 0 )
385                 {
386                         data_index = data_index + length;
387                         length = 0;
388                         goto READ_STREAM;
389                 }
390
391 #ifdef __INTERNAL_DEBUG__
392                 debug_printf("[ %s ] %s\r\n\r\n", request, data);
393 #endif
394         }
395         return true;
396 }
397
398 void Cble::streamDummy( char* data, int dataLen)
399 {
400         int cnt=0;
401         int length=0;
402         int required_length = dataLen;
403         char* data_index = data;
404
405         if( data && required_length )
406         {
407 READ_STREAM :
408                 while( (length=BLE.readBytes(data_index, required_length)) == 0 )
409                 {
410                         cnt++;
411                         if ( cnt >= LIMIT_COUNT )
412                         {
413                                 debug_printf("[ streamDummy ] TimeOut : No data.\r\n\r\n");
414                                 return ;
415                         }
416                 }
417
418                 required_length -= length;
419                 if( required_length != 0 )
420                 {
421                         data_index = data_index + length;
422                         length = 0;
423                         goto READ_STREAM;
424                 }
425
426                 debug_printf("[ streamDummy ] %s\r\n\r\n", data);
427         }
428         else
429         {
430                 if( BLE.available() )
431                 {
432                         BLE.readBytes(debugD, DEBUG_SIZE);
433 #ifdef __INTERNAL_DEBUG__
434                         debug_printf("[ streamDummy ] %s\r\n\r\n", debugD);
435 #endif
436                         memset(debugD, 0, DEBUG_SIZE);
437                 }
438         }
439
440 }
441
442 #if (ARDUINO != 0)
443
444 #define REGARD_DISCON                   5000
445 int needDiscon = 0;
446 unsigned long global_cnt = 0;
447
448 void Cble::BLE2Debug( int autoDiscon )
449 {
450         int cnt=0;
451         uint8_t length=0;
452
453         if( BLE.available() )
454         {
455                 while( (length=BLE.readBytes(BLEData, SERIAL_SIZE)) == 0 )
456                 {
457                         cnt++;
458                         if ( cnt >= LIMIT_COUNT )
459                                 return ;
460                 }
461
462                 global_cnt = 0;
463                 needDiscon = 0;
464
465                 Serial.println(BLEData);
466                 memset(BLEData, 0, length);
467         }
468         else if ( autoDiscon )
469         {
470                 global_cnt++;
471 //              debug_printf("global_cnt=%u , ", global_cnt );
472 //              debug_printf("needDiscon=%d\r\n", needDiscon);
473                 if( !needDiscon && global_cnt >= REGARD_DISCON )
474                 {
475                         needDiscon = 1;
476                         debug_printf("result : global_cnt=%u , ", global_cnt );
477                         debug_printf("needDiscon=%d\r\n", needDiscon);
478                 }
479
480                 if ( needDiscon )
481                 {
482                         debug_printf("Auto Discon : global_cnt=%u , ", global_cnt );
483                         debug_printf("needDiscon=%d\r\n", needDiscon);
484                         if( pollingRequest("AT", debugD, 2) == true )
485                         {
486                                 global_cnt = 0;
487                                 needDiscon = 0;
488                         }
489                 }
490         }
491 }
492
493 char* Cble::Debug2BLE( int BLEwrite )
494 {
495         char* result = NULL;
496
497         if( Serial.available() )
498         {
499                 char c = (char)Serial.read();
500
501                 switch(c)
502                 {
503                 case '\0':
504                         return result;
505                 case '\r':
506                 case '\n':
507                         debug_printf("\r\n");
508                         if(BLEwrite && SerialCnt)
509                         {
510                                 BLE.write(SerialData);
511                                 BLE.flush();
512                         }
513
514                         result = (char*)malloc(sizeof(char)*(SerialCnt+1));
515                         memcpy(result, SerialData, SerialCnt );
516                         result[SerialCnt] = NULL;
517
518                         memset(SerialData, 0, SerialCnt+1);
519                         SerialCnt=0;
520                         break;
521                 default :
522                         SerialData[SerialCnt] = c;
523                         SerialCnt++;
524                         Serial.print(c);
525                         break;
526                 }
527         }
528
529         return result;
530 }
531 #else
532 void Cble::BLE2Debug( int autoDiscon )
533 {
534         ;
535 }
536
537 char* Cble::Debug2BLE( int BLEwrite )
538 {
539          return NULL;
540 }
541 #endif
542
543 void Cble::FactoryReset( void )
544 {
545         debug_printf("FactoryReset is called.\r\n");
546
547         pollingRequest("AT+RENEW", debugD, 8);
548         memset(debugD, 0, DEBUG_SIZE);
549 }
550
551
552 void Cble::firstUartSetting( void )
553 {
554         debug_printf("firstUartSetting is called.\r\n");
555
556         Serial.begin(9600);
557         BLE.begin(9600);
558         BLE.setTimeout(1);
559         delay(1000);
560
561         pollingRequest("AT+BAUD4", debugD, 8);
562         memset(debugD, 0, DEBUG_SIZE);
563
564         debug_printf("Please Power off and on.\r\n");
565         BLE.end();
566 //      delay(1000);
567 //
568 //      BLE.begin(115200);
569 //      delay(1000);
570 //
571 //      pollingRequest("AT", debugD, DEBUG_SIZE);
572 //      memset(debugD, 0, DEBUG_SIZE);
573
574
575         exit(0);
576 }
577
578
579
580
581
582
583
584