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