Update: orig2001_11_27_05_17 -> orig2001_11_27_22_58
[gnokii.git] / common / phones / nk3110.c
1 /*
2
3   $Id$
4
5   G N O K I I
6
7   A Linux/Unix toolset and driver for Nokia mobile phones.
8
9   Copyright (C) 2000 Hugh Blemings & Pavel Janík ml.
10   Copyright (C) 2001 Pawe³ Kot <pkot@linuxnews.pl>
11
12   Released under the terms of the GNU GPL, see file COPYING for more details.
13
14   This file provides functions specific to the 3110 series. 
15   See README for more details on supported mobile phones.
16
17   $Log$
18   Revision 1.1.1.1.12.1  2001/11/27 23:34:48  short
19   Update: orig2001_11_27_05_17 -> orig2001_11_27_22_58
20
21   Revision 1.1.1.1.8.1  2001/11/27 23:06:09  short
22   Update: orig2001_11_27_05_17 -> orig2001_11_27_22_58
23
24   Revision 1.1.1.1.2.1  2001/11/27 22:48:37  short
25   Update: orig2001_11_27_05_17 -> orig2001_11_27_22_58
26
27   Revision 1.1.1.2  2001/11/27 22:01:20  short
28   :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Tue Nov 27 22:58 CET 2001
29
30   Revision 1.7  2001/11/27 12:19:01  pkot
31   Cleanup, indentation, ANSI complaint preprocesor symbols (Jan Kratochvil, me)
32
33   Revision 1.6  2001/11/20 16:22:22  pkot
34   First attempt to read Picture Messages. They should appear when you enable DEBUG. Nokia seems to break own standards. :/ (Markus Plail)
35
36   Revision 1.5  2001/11/19 13:03:18  pkot
37   nk3110.c cleanup
38
39   Revision 1.4  2001/11/17 16:42:47  pkot
40   Cleanup
41
42   Revision 1.3  2001/11/09 14:25:04  pkot
43   DEBUG cleanups
44
45   Revision 1.2  2001/11/09 13:47:58  pkot
46   Removed pthreads from 3110 support. It may break it.
47
48   Revision 1.1  2001/11/08 16:39:09  pkot
49   3810/3110 support for the new structure (Tamas Bondar)
50
51
52 */
53
54 #include <string.h>
55 #include <stdlib.h>
56 #include <ctype.h>
57
58 #define __phones_nk3110_c
59 #include "misc.h"
60 #include "gsm-common.h"
61 #include "phones/generic.h"
62 #include "phones/nk3110.h"
63 #include "links/fbus-3110.h"
64 #include "phones/nokia.h"
65
66 #ifndef WIN32
67 #  include <unistd.h>
68 #else
69 #  define snprintf _snprintf
70 #  define usleep(x) Sleep(((x) < 1000) ? 1 : ((x) / 1000))
71 #endif
72
73 /* Some globals */
74
75 static GSM_IncomingFunctionType IncomingFunctions[] = {
76         { 0x0a, P3110_IncomingNothing },
77         { 0x0b, P3110_IncomingCall },
78         { 0x0c, P3110_IncomingNothing },
79         { 0x0d, P3110_IncomingCallAnswered },
80         { 0x0e, P3110_IncomingCallEstablished },
81         { 0x0f, P3110_IncomingNothing },
82         { 0x10, P3110_IncomingEndOfOutgoingCall },
83         { 0x11, P3110_IncomingEndOfIncomingCall },
84         { 0x12, P3110_IncomingEndOfOutgoingCall2 },
85         { 0x13, P3110_IncomingRestart },
86         { 0x15, P3110_IncomingInitFrame_0x15 },
87         { 0x16, P3110_IncomingInitFrame_0x16 },
88         { 0x17, P3110_IncomingInitFrame_0x17 },
89         { 0x20, P3110_IncomingNothing },
90         /*{ 0x21, P3110_IncomingDTMFSucess },*/
91         /*{ 0x22, P3110_IncomingDTMFFailure },*/
92         { 0x23, P3110_IncomingNothing },
93         { 0x24, P3110_IncomingNothing },
94         { 0x25, P3110_IncomingNothing },
95         { 0x26, P3110_IncomingNothing },
96         { 0x27, P3110_IncomingSMSUserData },
97         { 0x28, P3110_IncomingSMSSend },
98         { 0x29, P3110_IncomingSMSSendError },
99         /* ... */
100         { 0x2c, P3110_IncomingSMSHeader },
101         { 0x2d, P3110_IncomingSMSError },
102         { 0x2e, P3110_IncomingSMSDelete },
103         { 0x2f, P3110_IncomingSMSDeleteError },
104         /* ... */
105         { 0x32, P3110_IncomingSMSDelivered },
106         { 0x3f, P3110_IncomingNothing },
107         { 0x40, P3110_IncomingNoSMSInfo },
108         { 0x41, P3110_IncomingSMSInfo },
109         { 0x48, P3110_IncomingPINEntered },
110         { 0x4a, P3110_IncomingNothing },
111         { 0x4b, P3110_IncomingStatusInfo },
112         { 0x4c, P3110_IncomingNothing },
113         { 0x4d, P3110_IncomingPhoneInfo },
114         { 0, NULL}
115 };
116
117 GSM_Phone phone_nokia_3110 = {
118         IncomingFunctions,
119         PGEN_IncomingDefault,
120         /* Mobile phone information */
121         {
122                 "3110|3810|8110|8110i", /* Models */
123                 4,                      /* Max RF Level */
124                 0,                      /* Min RF Level */
125                 GRF_Arbitrary,          /* RF level units */
126                 4,                      /* Max Battery Level */
127                 0,                      /* Min Battery Level */
128                 GBU_Arbitrary,          /* Battery level units */
129                 GDT_None,               /* No date/time support */
130                 GDT_None,               /* No alarm support */
131                 0,                      /* Max alarms = 0 */
132                 0, 0,                   /* Startup logo size */
133                 0, 0,                   /* Op logo size */
134                 0, 0                    /* Caller logo size */
135         },
136         Functions
137 };
138
139 static GSM_Error Functions(GSM_Operation op, GSM_Data *data, GSM_Statemachine *state)
140 {
141         switch (op) {
142         case GOP_Init:
143                 return P3110_Initialise(state);
144         case GOP_GetModel:
145         case GOP_GetRevision:
146         case GOP_GetImei:
147                 return P3110_GetPhoneInfo(data, state);
148         case GOP_Identify:
149                 return P3110_Identify(data, state);
150         case GOP_GetBatteryLevel:
151         case GOP_GetRFLevel:
152                 return P3110_GetStatusInfo(data, state);
153         case GOP_GetMemoryStatus:
154                 return P3110_GetMemoryStatus(data, state);
155         case GOP_ReadPhonebook:
156         case GOP_WritePhonebook:
157         case GOP_GetPowersource:
158         case GOP_GetAlarm:
159         case GOP_GetSMSStatus:
160         case GOP_GetIncomingCallNr:
161         case GOP_GetNetworkInfo:
162                 return GE_NOTIMPLEMENTED;
163         case GOP_GetSMS:
164                 return P3110_GetSMSMessage(data, state);
165         case GOP_DeleteSMS:
166                 return P3110_DeleteSMSMessage(data, state);
167         case GOP_SendSMS:
168                 return P3110_SendSMSMessage(data, state);
169         case GOP_GetSMSCenter:
170                 return P3110_GetSMSInfo(data, state);
171         case GOP_GetSpeedDial:
172         case GOP_GetDateTime:
173         default:
174                 return GE_NOTIMPLEMENTED;
175         }
176 }
177
178 static bool LinkOK = false;
179 static bool SimAvailable = false;
180
181 /* These are related to keepalive functionality */
182 static bool RequestTerminate;
183 static bool DisableKeepAlive;
184 static int KeepAliveTimer;
185
186 /* Initialise is the only function allowed to 'use' state */
187 static GSM_Error P3110_Initialise(GSM_Statemachine *state)
188 {
189         GSM_Data data;
190         u8 init_sequence[20] = {0x02, 0x01, 0x07, 0xa2, 0x88, 0x81, 0x21, 0x55, 0x63, 0xa8, 0x00, 0x00, 0x07, 0xa3, 0xb8, 0x81, 0x20, 0x15, 0x63, 0x80};
191
192         /* Copy in the phone info */
193         memcpy(&(state->Phone), &phone_nokia_3110, sizeof(GSM_Phone));
194
195         /* Only serial connection is supported */
196         if (state->Link.ConnectionType != GCT_Serial) return GE_NOTSUPPORTED;
197
198         /* Initialise FBUS link */
199         if (FB3110_Initialise(&(state->Link), state) != GE_NONE) {
200                 dprintf("Error in link initialisation\n");
201                 return GE_NOTREADY;
202         }
203
204         /* Initialise state machine */
205         SM_Initialise(state);
206
207         /* 0x15 messages are sent by the PC during the initialisation phase.
208            Anyway, the contents of the message are not understood so we 
209            simply send the same sequence observed between the W95 PC and 
210            the phone.  The init sequence may still be a bit flaky and is not 
211            fully understood. */
212         if (SM_SendMessage(state, 20, 0x15, init_sequence) != GE_NONE) return GE_NOTREADY;
213
214         /* Wait for response to 0x15 sequence */
215         GSM_DataClear(&data);
216         if (SM_Block(state, &data, 0x16) != GE_NONE) return GE_NOTREADY;
217
218         /* Most probably link is OK now */
219         LinkOK = true;
220
221         /* Start sending keepalive messages in separate thread */
222         KeepAliveTimer = P3110_KEEPALIVE_TIMEOUT;
223         RequestTerminate = false;
224         DisableKeepAlive = false;
225         return GE_NONE;
226 }
227
228
229 static GSM_Error P3110_GetSMSInfo(GSM_Data *data, GSM_Statemachine *state)
230 {
231         KeepAliveTimer = P3110_KEEPALIVE_TIMEOUT;
232         if (SM_SendMessage(state, 0, 0x3f, NULL) != GE_NONE) return GE_NOTREADY;
233         return SM_Block(state, data, 0x41);
234 }
235
236 static GSM_Error P3110_GetPhoneInfo(GSM_Data *data, GSM_Statemachine *state)
237 {
238         dprintf("Getting phone info...\n");
239         KeepAliveTimer = P3110_KEEPALIVE_TIMEOUT;
240         if (SM_SendMessage(state, 0, 0x4c, NULL) != GE_NONE) return GE_NOTREADY;
241         return SM_Block(state, data, 0x4d);
242 }
243
244 static GSM_Error P3110_GetStatusInfo(GSM_Data *data, GSM_Statemachine *state)
245 {
246         dprintf("Getting phone status...\n");
247         KeepAliveTimer = P3110_KEEPALIVE_TIMEOUT;
248         if (SM_SendMessage(state, 0, 0x4a, NULL) != GE_NONE) return GE_NOTREADY;
249         return SM_Block(state, data, 0x4b);
250 }
251
252 static GSM_Error P3110_GetMemoryStatus(GSM_Data *data, GSM_Statemachine *state)
253 {
254         dprintf("Getting memory status...\n");
255
256         /* Check if this type of memory is available */
257         switch (data->MemoryStatus->MemoryType) {
258         case GMT_SM:
259                 if (!SimAvailable) return GE_NOTREADY;
260                 return P3110_GetSMSInfo(data, state);
261         case GMT_ME:
262                 if (P3110_MEMORY_SIZE_ME == 0) return GE_NOTREADY;
263                 return P3110_GetSMSInfo(data, state);
264         default:
265                 break;
266         }
267         return GE_NOTREADY;
268 }
269
270
271 static GSM_Error P3110_Identify(GSM_Data *data, GSM_Statemachine *state)
272 {
273         dprintf("Identifying...\n");
274         KeepAliveTimer = P3110_KEEPALIVE_TIMEOUT;
275         if (SM_SendMessage(state, 0, 0x4c, NULL) != GE_NONE) return GE_NOTREADY;
276         SM_Block(state, data, 0x4d);
277         
278         /* Check that we are back at state Initialised */
279         if (SM_Loop(state, 0) != Initialised) return GE_UNKNOWN;
280         return GE_NONE;
281 }
282
283
284 static GSM_Error P3110_GetSMSMessage(GSM_Data *data, GSM_Statemachine *state)
285 {
286         int total_length, timeout, c;
287         u8 response = 0, request[2];
288         GSM_Error error = GE_INTERNALERROR;
289
290         dprintf("Getting SMS message...\n");
291
292         KeepAliveTimer = P3110_KEEPALIVE_TIMEOUT;
293
294         switch(data->SMSMessage->MemoryType) {
295         case GMT_ME:
296                 data->SMSMessage->MemoryType = 1; /* 3 in 8110, 1 is GMT_CB */
297                 break;
298         case GMT_SM:
299                 data->SMSMessage->MemoryType = 2;
300                 break;
301         default:
302                 return (GE_INVALIDMEMORYTYPE);
303         }
304
305         /* Set memory type and location in the request */
306         request[0] = data->SMSMessage->MemoryType;
307         request[1] = data->SMSMessage->Number;
308
309         /* 0x25 messages requests the contents of an SMS message
310            from the phone.  The first byte has only ever been 
311            observed to be 0x02 - could be selecting internal versus
312            external memory.  Specifying memory 0x00 may request the
313            first location?  Phone replies with 0x2c and 0x27 messages
314            for valid locations, 0x2d for empty ones. */
315         if (SM_SendMessage(state, 2, 0x25, request) != GE_NONE) return GE_NOTREADY;
316
317         SM_WaitFor(state, data, 0x2d);
318         SM_WaitFor(state, data, 0x2c);
319
320         timeout = 30; /* ~3secs timeout */
321
322         do {
323                 SM_Loop(state, 1);
324                 timeout--;
325         } while ((timeout > 0) && state->NumReceived == 0);
326
327         /* timeout */ 
328         if (state->NumReceived == 0) return GE_TIMEOUT;
329
330         /* find response in state machine */
331         for (c = 0; c < state->NumWaitingFor; c++) {
332                 if (state->ResponseError[c] != GE_BUSY) {
333                         response = state->WaitingFor[c];
334                         error = state->ResponseError[c];
335                 }
336         }
337
338         /* reset state machine */
339         SM_Reset(state);
340
341         /* process response */
342         switch (response) {
343         case 0x2c:
344                 if (error != GE_NONE) return error;
345
346                 /* Save total length of message */
347                 total_length = data->SMSMessage->Length;
348
349                 /* Block for subsequent content frames... */
350                 do {
351                         SM_Block(state, data, 0x27);
352                 } while (data->SMSMessage->Length < total_length);
353
354                 /* Terminate message text */
355                 data->SMSMessage->MessageText[data->SMSMessage->Length] = 0;
356                 return GE_NONE;
357         case 0x2d:
358                 return error;
359         default:
360                 return GE_INTERNALERROR;
361         }
362 }
363
364
365 static GSM_Error P3110_DeleteSMSMessage(GSM_Data *data, GSM_Statemachine *state)
366 {
367         int timeout, c;
368         u8 response = 0, request[2];
369         GSM_Error error = GE_INTERNALERROR;
370
371         dprintf("Deleting SMS message...\n");
372
373         KeepAliveTimer = P3110_KEEPALIVE_TIMEOUT;
374
375         switch(data->SMSMessage->MemoryType) {
376         case GMT_ME:
377                 data->SMSMessage->MemoryType = 1; /* 3 in 8110, 1 is GMT_CB */
378                 break;
379         case GMT_SM:
380                 data->SMSMessage->MemoryType = 2;
381                 break;
382         default:
383                 return (GE_INVALIDMEMORYTYPE);
384         }
385
386         /* Set memory type and location in the request */
387         request[0] = data->SMSMessage->MemoryType;
388         request[1] = data->SMSMessage->Number;
389
390         /* 0x26 message deletes an SMS message from the phone. 
391            The first byte has only ever been observed to be 0x02
392            but is assumed to be selecting internal versus
393            external memory.  Phone replies with 0x2e for valid locations,
394            0x2f for invalid ones.  If a location is empty but otherwise
395            valid 0x2e is still returned. */
396         if (SM_SendMessage(state, 2, 0x26, request) != GE_NONE) return GE_NOTREADY;
397
398         SM_WaitFor(state, data, 0x2e);
399         SM_WaitFor(state, data, 0x2f);
400
401         timeout = 30; /* ~3secs timeout */
402
403         do {
404                 SM_Loop(state, 1);
405                 timeout--;
406         } while ((timeout > 0) && state->NumReceived == 0);
407
408         /* timeout */ 
409         if (state->NumReceived == 0) return GE_TIMEOUT;
410
411         /* find response in state machine */
412         for (c = 0; c < state->NumWaitingFor; c++) {
413                 if (state->ResponseError[c] != GE_BUSY) {
414                         response = state->WaitingFor[c];
415                         error = state->ResponseError[c];
416                 }
417         }
418
419         /* reset state machine */
420         SM_Reset(state);
421
422         /* process response */
423         switch (response) {
424         case 0x2e:
425         case 0x2f:
426                 return error;
427         default:
428                 return GE_INTERNALERROR;
429         }
430 }
431
432
433 static GSM_Error P3110_SendSMSMessage(GSM_Data *data, GSM_Statemachine *state)
434 {
435         int timeout, c, retry_count, block_count, block_length;
436         u8 userdata[GSM_MAX_SMS_LENGTH];
437         int userdata_length, userdata_offset, userdata_remaining;
438         u8 response, request[GSM_MAX_SMS_LENGTH];
439         GSM_Error error;
440         SMS_MessageCenter smsc;
441         int i;
442
443         /* Get default SMSC from phone if not set in SMS */
444         if (!data->SMSMessage->MessageCenter.Number[0]) {
445                 data->MessageCenter = &smsc;
446                 error = P3110_GetSMSInfo(data, state);
447                 if (error != GE_NONE) return error;
448                 data->SMSMessage->MessageCenter = smsc;
449         }
450
451         dprintf("Sending SMS to %s via message center %s\n", data->SMSMessage->RemoteNumber.number, data->SMSMessage->MessageCenter.Number);
452
453 /*
454   Moved to gsm-sms.c
455   if (data->SMSMessage->UDH[0].Type) {
456   userdata_offset = 1 + data->SMSMessage->udhlen;
457   memcpy(userdata, data->SMSMessage->MessageText, userdata_offset);
458   fo |= FO_UDHI;
459   } else {
460   userdata_offset = 0;
461   }
462 */
463
464 /*
465   Moved to gsm-sms.c
466   if (data->SMSMessage->EightBit) {
467   memcpy(userdata + userdata_offset, data->SMSMessage->MessageText, data->SMSMessage->Length);
468   userdata_length = data->SMSMessage->Length + userdata_offset;
469   max_userdata_length = GSM_MAX_SMS_8_BIT_LENGTH;
470   dcs = DCS_DATA | DCS_CLASS1;
471   } else {
472   userdata_length = strlen(data->SMSMessage->MessageText);
473   memcpy(userdata + userdata_offset, data->SMSMessage->MessageText, userdata_length);
474   userdata_length += userdata_offset;
475   max_userdata_length = GSM_MAX_SMS_LENGTH;
476   }
477 */
478
479 /*
480   Moved to gsm-sms.c
481   request[0] = fo;
482   request[1] = PID_DEFAULT;
483   request[2] = dcs;
484   request[3] = GSMV_Max_Time;
485   request[4] = 0x00;
486   request[5] = 0x00;
487   request[6] = 0x00;
488   request[7] = 0x00;
489   request[8] = 0x00;
490   request[9] = 0x00;
491   request[10] = userdata_length;
492   request[11] = smsc_length;
493   memcpy(request+12, data->SMSMessage->MessageCenter.Number, smsc_length);
494   request[12+smsc_length] = dest_length;
495   memcpy(request+13+smsc_length, data->SMSMessage->Destination, dest_length);
496 */
497
498         error = EncodePDUSMS(data->SMSMessage, request);
499         if (error) return error;
500
501         /* We have a loop here as if the response from the phone is
502            0x65 0x26 the rule appears to be just to try sending the
503            message again.  We do this a maximum of FB38_SMS_SEND_RETRY_COUNT
504            times before giving up.  This value is empirical only! */
505         retry_count = P3110_SMS_SEND_RETRY_COUNT;
506
507         while (retry_count > 0) {
508
509                 KeepAliveTimer = P3110_KEEPALIVE_TIMEOUT;
510
511                 dprintf("Transferring FBUS SMS header [");
512                 for (i = 0; i < data->SMSMessage->Length; i++) dprintf(" %02hhX", request[i]);
513                 dprintf(" ]\n");
514
515                 if (SM_SendMessage(state, data->SMSMessage->Length, 0x23, request) != GE_NONE) return GE_NOTREADY;
516
517                 error = SM_Block(state, data, 0x23);
518                 if (error != GE_NONE) return error;
519
520                 /* Now send as many blocks of maximum 55 characters as required
521                    to send complete message. */
522                 block_count = 1;
523                 userdata_offset = 0;
524                 userdata_remaining = userdata_length;
525
526                 while (userdata_remaining > 0) {
527                         block_length = userdata_remaining;
528
529                         /* Limit block length */
530                         if (block_length > 55) block_length = 55;
531
532                         /* Create block */
533                         request[0] = block_count;
534                         memcpy(request+1, userdata + userdata_offset, block_length);
535
536                         /* Send block */
537                         if (SM_SendMessage(state, block_length+1, 0x27, request) != GE_NONE) return GE_NOTREADY;
538                         error = SM_Block(state, data, 0x27);
539                         if (error != GE_NONE) return error;
540
541                         /* update remaining and offset values for next block */
542                         userdata_remaining -= block_length;
543                         userdata_offset += block_length;
544                         block_count ++;
545                 }
546
547                 /* Now wait for response from network which will see
548                    CurrentSMSMessageError change from busy. */
549                 SM_WaitFor(state, data, 0x28);
550                 SM_WaitFor(state, data, 0x29);
551
552                 timeout = 1200; /* 120secs timeout */
553
554                 do {
555                         SM_Loop(state, 1);
556                         timeout--;
557                 } while ((timeout > 0) && state->NumReceived == 0);
558
559                 /* timeout */ 
560                 if (state->NumReceived == 0) return GE_TIMEOUT;
561
562                 /* find response in state machine */
563                 for (c = 0; c < state->NumWaitingFor; c++) {
564                         if (state->ResponseError[c] != GE_BUSY) {
565                                 response = state->WaitingFor[c];
566                                 error = state->ResponseError[c];
567                         }
568                 }
569
570                 /* reset state machine */
571                 SM_Reset(state);
572
573                 /* process response */
574                 switch (response) {
575                 case 0x28:
576                         return error;
577                 case 0x29:
578                         /* Got a retry response so try again! */
579                         dprintf("SMS send attempt failed, trying again...\n");
580                         retry_count--;
581                         /* After an empirically determined pause... */
582                         usleep(500000); /* 0.5 seconds. */
583                         break;
584                 default:
585                         return GE_INTERNALERROR;
586                 }
587         }
588         /* Retries must have failed. */
589         return GE_SMSSENDFAILED;
590 }
591
592
593 static GSM_Error P3110_IncomingNothing(int messagetype, unsigned char *message, int length, GSM_Data *data)
594 {
595         return GE_NONE;
596 }
597
598 /* 0x0b messages are sent by phone when an incoming call occurs,
599    this message must be acknowledged. */
600 static GSM_Error P3110_IncomingCall(int messagetype, unsigned char *message, int length, GSM_Data *data)
601 {
602         int     count;
603         char    buffer[256];
604
605         /* Get info out of message.  At present, first three bytes are 
606            unknown (though third seems to correspond to length of 
607            number).  Remaining bytes are the phone number, ASCII 
608            encoded. */
609         for (count = 0; count < message[4]; count ++) {
610                 buffer[count] = message[5 + count];
611         }
612         buffer[count] = 0x00;
613
614         /* Now display incoming call message. */
615         dprintf("Incoming call - Type: %s. %02x, Number %s.\n",
616                 (message[2] == 0x05 ? "Voice":"Data?"), message[3], buffer);
617
618         return GE_NONE;
619 }
620
621 static GSM_Error P3110_IncomingCallAnswered(int messagetype, unsigned char *message, int length, GSM_Data *data)
622 {
623         dprintf("Incoming call answered from phone.\n");
624
625         return GE_NONE;
626 }
627
628 /* Fairly self explanatory these two, though the outgoing 
629    call message has three (unexplained) data bytes. */
630 static GSM_Error P3110_IncomingCallEstablished(int messagetype, unsigned char *message, int length, GSM_Data *data)
631 {
632         dprintf("%s call established - status bytes %02x %02x.\n",
633                 (message[2] == 0x05 ? "voice":"data(?)"), message[3], message[4]);
634
635         return GE_NONE;
636 }
637
638 /* 0x10 messages are sent by the phone when an outgoing
639    call terminates. */
640 static GSM_Error P3110_IncomingEndOfOutgoingCall(int messagetype, unsigned char *message, int length, GSM_Data *data)
641 {
642         dprintf("Call terminated from phone (0x10 message).\n");
643         /* FIXME: Tell datapump code that the call has terminated. */
644         /*if (CallPassup) {
645                 CallPassup(' ');
646                 }*/
647
648         return GE_NONE;
649 }
650
651 /* 0x11 messages are sent by the phone when an incoming call
652    terminates.  There is some other data in the message, 
653    purpose as yet undertermined. */
654 static GSM_Error P3110_IncomingEndOfIncomingCall(int messagetype, unsigned char *message, int length, GSM_Data *data)
655 {
656         dprintf("Call terminated from opposite end of line (or from network).\n");
657
658         /* FIXME: Tell datapump code that the call has terminated. */
659         /*if (CallPassup) {
660                 CallPassup(' ');
661                 }*/
662
663         return GE_NONE;
664 }
665
666 /* 0x12 messages are sent after the 0x10 message at the 
667    end of an outgoing call.  Significance of two messages
668    versus the one at the end of an incoming call  is as 
669    yet undertermined. */
670 static GSM_Error P3110_IncomingEndOfOutgoingCall2(int messagetype, unsigned char *message, int length, GSM_Data *data)
671 {
672         dprintf("Call terminated from phone (0x12 message).\n");
673
674         /* FIXME: Tell datapump code that the call has terminated. */
675         /*if (CallPassup) {
676                 CallPassup(' ');
677                 }*/
678
679         return GE_NONE;
680 }
681
682
683 /* 0x13 messages are sent after the phone restarts. 
684    Re-initialise */
685
686 static GSM_Error P3110_IncomingRestart(int messagetype, unsigned char *message, int length, GSM_Data *data)
687 {
688         /* FIXME: send 0x15 message somehow */
689         return GE_NONE;
690 }
691
692
693 /* 0x15 messages are sent by the phone in response to the
694    init sequence sent so we don't acknowledge them! */
695
696 static GSM_Error P3110_IncomingInitFrame_0x15(int messagetype, unsigned char *message, int length, GSM_Data *data)
697 {
698         return GE_NONE;
699 }
700
701
702 /* 0x16 messages are sent by the phone during initialisation, to response 
703    to the 0x15 message.
704    Sequence bytes have been observed to change with differing software 
705    versions: V06.61 (19/08/97) sends 0x10 0x02, V07.02 (17/03/98) sends 
706    0x30 0x02. The actual data byte is 0x02 when SIM memory is available,
707    and 0x01 when not (e.g. when SIM card isn't inserted to phone or when 
708    it is waiting for PIN) */
709
710 static GSM_Error P3110_IncomingInitFrame_0x16(int messagetype, unsigned char *message, int length, GSM_Data *data)
711 {
712         SimAvailable = (message[2] == 0x02);
713         dprintf("SIM available: %s.\n", (SimAvailable ? "Yes" : "No"));
714         return GE_NONE;
715 }
716
717
718 static GSM_Error P3110_IncomingInitFrame_0x17(int messagetype, unsigned char *message, int length, GSM_Data *data)
719 {
720         dprintf("0x17 Registration Response: Failure!\n");
721         return GE_NONE;
722 }
723
724
725 /* 0x27 messages are a little unusual when sent by the phone in that
726    they can either be an acknowledgement of an 0x27 message we sent
727    to the phone with message text in it or they could
728    contain message text for a message we requested. */
729
730 static GSM_Error P3110_IncomingSMSUserData(int messagetype, unsigned char *message, int length, GSM_Data *data)
731 {
732         int count;
733     
734         /* First see if it was an acknowledgement to one of our messages,
735            if so then nothing to do */
736         if (length == 0x02) return GE_NONE;
737
738         /* Copy into current SMS message as long as it's non-NULL */
739         if (!data->SMSMessage) return GE_INTERNALERROR;
740
741         /* If this is the first block, reset accumulated message length. */
742         if (message[2] == 1) data->SMSMessage->Length = 0;
743
744         /* Copy message text */
745         for (count = 0; count < length-3 && data->SMSMessage->Length < GSM_MAX_SMS_LENGTH; count++, data->SMSMessage->Length++)
746                 data->SMSMessage->MessageText[data->SMSMessage->Length] = message[count + 3];
747
748         return GE_NONE;
749 }
750
751
752 /* 0x28 messages are sent by the phone to acknowledge succesfull
753    sending of an SMS message.  The byte returned is a receipt
754    number of some form, not sure if it's from the network, sending
755    sending of an SMS message.  The byte returned is the TP-MR
756    (TP-Message-Reference) from sending phone (Also sent to network).
757    TP-MR is send from phone within 0x32 message. TP-MR is increased
758    by phone after each sent SMS */
759
760 static GSM_Error P3110_IncomingSMSSend(int messagetype, unsigned char *message, int length, GSM_Data *data)
761 {
762         dprintf("SMS send OK (0x%02hhx)\n", message[2]);
763         data->SMSMessage->Number = (int) message[2];
764         return GE_SMSSENDOK;
765 }
766
767
768 /* 0x29 messages are sent by the phone to indicate an error in
769    sending an SMS message.  Observed values are 0x65 0x15 when
770    the phone originated SMS was disabled by the network for
771    the particular phone.  0x65 0x26 was observed too, whereupon
772    the message was retried. */
773
774 static GSM_Error P3110_IncomingSMSSendError(int messagetype, unsigned char *message, int length, GSM_Data *data)
775 {
776         dprintf("SMS send failed (0x%02hhx 0x%02hhx)\n", message[2], message[3]);
777         return GE_SMSSENDFAILED;
778 }
779
780
781 /* 0x2c messages are generated by the phone when we request an SMS 
782    message with an 0x25 message.  Appears to have the same fields 
783    as the 0x30 notification but with one extra.  Immediately after 
784    the 0x2c nessage, the phone sends 0x27 message(s) */
785
786 static GSM_Error P3110_IncomingSMSHeader(int messagetype, unsigned char *message, int length, GSM_Data *data)
787 {
788         /* u8 sender_length, smsc_length, l; */
789
790         if (!data->SMSMessage) return GE_INTERNALERROR;
791
792         /* Extract data from message into SMSMessage */
793
794         DecodePDUSMS(message, data->SMSMessage, length);
795
796         /* All these moved to gsm-sms.c
797         Set memory type
798         switch(message[2]) {
799         case 1:
800                 data->SMSMessage->MemoryType = GMT_ME;
801                 break;
802         case 2:
803                 data->SMSMessage->MemoryType = GMT_SM;
804                 break;
805         default:
806                 data->SMSMessage->MemoryType = GMT_XX;
807                 break;
808         }
809
810         Set location in memory
811         data->SMSMessage->Location = message[3];
812         data->SMSMessage->MessageNumber = message[3];
813
814           3810 series has limited support for different SMS "mailboxes"
815            to the extent that the only know differentiation is between
816            received messages 0x01, 0x04 and written messages 0x07 0x01.
817            No flag has been found (yet) that indicates whether the 
818            message has been sent or not.
819
820         Default to unknown message type
821         data->SMSMessage->Type = GST_UN;
822
823         Consider received messages "Inbox" (Mobile Terminated)
824         if (message[4] == 0x01 && message[5] == 0x04)
825                 data->SMSMessage->Type = GST_MT;
826
827         Consider written messages "Outbox" (Mobile Originated)
828         if (message[4] == 0x07 && message[5] == 0x01)
829                 data->SMSMessage->Type = GST_MO;
830
831         We don't know about read/unread or sent/unsent status.
832            so assume has been sent or read
833         data->SMSMessage->Status = GSS_SENTREAD;
834
835         Based on experiences with a 3110 it seems, that
836            0x03 means a received unread message,
837            0x07 means a stored unsent message
838         if (message[4] == 0x03 || message[4] == 0x07)
839                 data->SMSMessage->Status = GSS_NOTSENTREAD;
840         else
841                 data->SMSMessage->Status = GSS_SENTREAD;
842
843         Check UDHI
844         if (message[5] & FO_UDHI)
845                 data->SMSMessage->UDHType = GSM_RingtoneUDH; FIXME
846         else
847                 data->SMSMessage->UDHType = GSM_NoUDH;
848
849         Check Data Coding Scheme and set text/binary flag
850         if (message[7] == 0xf5)
851                 data->SMSMessage->EightBit = true;
852         else
853                 data->SMSMessage->EightBit = false;
854
855         Extract date and time information which is packed in to 
856            nibbles of each byte in reverse order.  Thus day 28 would be
857            encoded as 0x82
858         P3110_DecodeTime(message+8, &(data->SMSMessage->Time));
859
860         Set message length
861         data->SMSMessage->Length = message[15];
862
863         Now get sender and message center length
864         smsc_length = message[16];
865         sender_length = message[17 + smsc_length];
866
867         Copy SMSC number
868         l = smsc_length < GSM_MAX_SMS_CENTER_LENGTH ? smsc_length : GSM_MAX_SMS_CENTER_LENGTH;
869         strncpy(data->SMSMessage->MessageCenter.Number, message + 17, l);
870         data->SMSMessage->MessageCenter.Number[l] = 0;
871
872         Copy sender number
873         l = sender_length < GSM_MAX_SENDER_LENGTH ? sender_length : GSM_MAX_SENDER_LENGTH;
874         strncpy(data->SMSMessage->Sender, message + 18 + smsc_length, l);
875         data->SMSMessage->Sender[l] = 0;
876 */
877
878         dprintf("PID:%02x DCS:%02x Timezone:%02x Stat1:%02x Stat2:%02x\n",
879                 message[6], message[7], message[14], message[4], message[5]);
880
881         dprintf("Message Read:\n");
882         dprintf("  Location: %d. Type: %d Status: %d\n", data->SMSMessage->Number, data->SMSMessage->Type, data->SMSMessage->Status);
883         dprintf("  Sender: %s\n", data->SMSMessage->RemoteNumber.number);
884         dprintf("  Message Center: %s\n", data->SMSMessage->MessageCenter.Number);
885         dprintf("  Time: %02d.%02d.%02d %02d:%02d:%02d\n",
886                 data->SMSMessage->Time.Day, data->SMSMessage->Time.Month, data->SMSMessage->Time.Year, data->SMSMessage->Time.Hour, data->SMSMessage->Time.Minute, data->SMSMessage->Time.Second);
887
888         return GE_NONE;
889 }
890
891
892 /* 0x2d messages are generated when an SMS message is requested
893    that does not exist or is empty. */
894
895 static GSM_Error P3110_IncomingSMSError(int messagetype, unsigned char *message, int length, GSM_Data *data)
896 {
897         if (message[2] == 0x74)
898                 return GE_INVALIDSMSLOCATION;
899         else
900                 return GE_EMPTYSMSLOCATION;
901 }
902
903
904 /* 0x2e messages are generated when an SMS message is deleted
905    successfully. */
906
907 static GSM_Error P3110_IncomingSMSDelete(int messagetype, unsigned char *message, int length, GSM_Data *data)
908 {
909         return GE_NONE;
910 }
911
912
913 /* 0x2f messages are generated when an SMS message is deleted
914    that does not exist.  Unlike responses to a getsms message
915    no error is returned when the entry is already empty */
916
917 static GSM_Error P3110_IncomingSMSDeleteError(int messagetype, unsigned char *message, int length, GSM_Data *data)
918 {
919         /* Note 0x74 is the only value that has been seen! */
920         if (message[2] == 0x74)
921                 return GE_INVALIDSMSLOCATION;
922         else
923                 return GE_EMPTYSMSLOCATION;
924 }
925
926
927 /* 0x32 messages are generated when delivery notification arrives
928    to phone from network */
929
930 static GSM_Error P3110_IncomingSMSDelivered(int messagetype, unsigned char *message, int length, GSM_Data *data)
931 {
932         static GSM_SMSMessage sms;
933 /*      u8 dest_length, smsc_length, l;*/
934         u8 U0, U1, U2;
935
936         data->SMSMessage = &sms;
937
938         if (!data->SMSMessage) return GE_INTERNALERROR;
939
940         U0 = message[1];
941         U1 = message[2];
942         U2 = message[17];
943
944         DecodePDUSMS(message, data->SMSMessage, length);
945
946         /* All these are moved fo gsm-sms.c
947         P3110_DecodeTime(message+3, &(data->SMSMessage->Time));
948         P3110_DecodeTime(message+10, &(data->SMSMessage->SMSCTime));
949
950
951         Get message id
952         data->SMSMessage->MessageNumber = (int) message[18];
953
954         Get sender and message center length
955         dest_length = message[19];
956         smsc_length = message[20 + dest_length];
957
958         Copy destination number
959         l = dest_length < GSM_MAX_DESTINATION_LENGTH ? dest_length : GSM_MAX_DESTINATION_LENGTH;
960         strncpy(data->SMSMessage->Destination, message + 20, l);
961         data->SMSMessage->Destination[l] = 0;
962
963         Copy SMSC number
964         l = smsc_length < GSM_MAX_SMS_CENTER_LENGTH ? smsc_length : GSM_MAX_SMS_CENTER_LENGTH;
965         strncpy(data->SMSMessage->MessageCenter.Number, message + 21 + dest_length, l);
966         data->SMSMessage->MessageCenter.Number[l] = 0;
967         */
968
969         dprintf("Message [0x%02x] Delivered!\n", data->SMSMessage->Number);
970         dprintf("   Destination: %s\n", data->SMSMessage->RemoteNumber.number);
971         dprintf("   Message Center: %s\n", data->SMSMessage->MessageCenter.Number);
972         dprintf("   Unknowns: 0x%02x 0x%02x 0x%02x\n", U0, U1, U2);
973         dprintf("   Discharge Time: %02d.%02d.%02d %02d:%02d:%02d\n",
974                 data->SMSMessage->Time.Day, data->SMSMessage->Time.Month, data->SMSMessage->Time.Year, data->SMSMessage->Time.Hour, data->SMSMessage->Time.Minute, data->SMSMessage->Time.Second);
975         dprintf("   SMSC Time Stamp:  %02d.%02d.%02d %02d:%02d:%02d\n",
976                 data->SMSMessage->SMSCTime.Day, data->SMSMessage->SMSCTime.Month, data->SMSMessage->SMSCTime.Year, data->SMSMessage->SMSCTime.Hour, data->SMSMessage->SMSCTime.Minute, data->SMSMessage->SMSCTime.Second);
977
978         return GE_NONE;
979 }
980
981
982 /* 0x40 Messages are sent to response to an 0x3f request.
983    e.g. when phone is waiting for PIN */
984
985 static GSM_Error P3110_IncomingNoSMSInfo(int messagetype, unsigned char *message, int length, GSM_Data *data)
986 {
987         dprintf("SMS Message Center Data not reachable.\n");
988         return GE_NOTREADY;
989 }
990
991
992 /* Handle 0x41 message which is sent by phone in response to an
993    0x3f request.  Contains data about the Message Center in use */
994
995 static GSM_Error P3110_IncomingSMSInfo(int messagetype, unsigned char *message, int length, GSM_Data *data)
996 {
997         u8 center_number_length;
998         u8 option_number_length;
999         int count;
1000
1001         if (!data) return GE_INTERNALERROR;
1002
1003         /* We don't know what this option number is, just handle it */
1004         option_number_length = message[12];
1005
1006         /* Get message center length */
1007         center_number_length = message[13 + option_number_length];
1008
1009         dprintf("SMS Message Center Data:\n");
1010         dprintf("   Selected memory: 0x%02x\n", message[2]);
1011         dprintf("   Messages in Phone: 0x%02x Unread: 0x%02x\n", message[3], message[4]);
1012         dprintf("   Messages in SIM: 0x%02x Unread: 0x%02x\n", message[5], message[6]);
1013         dprintf("   Reply via own centre: 0x%02x (%s)\n", message[10], (message[10] == 0x02 ? "Yes" : "No"));
1014         dprintf("   Delivery reports: 0x%02x (%s)\n", message[11], (message[11] == 0x02 ? "Yes" : "No"));
1015         dprintf("   Messages sent as: 0x%02x\n", message[7]);
1016         dprintf("   Message validity: 0x%02x\n", message[9]);
1017         dprintf("   Unknown: 0x%02x\n", message[8]);
1018
1019         dprintf("   UnknownNumber: ");
1020         for (count = 0; count < option_number_length; count ++)
1021                 dprintf("%c", message[13 + count]);
1022         dprintf("\n");
1023
1024         dprintf("   Message center number: ");
1025         for (count = 0; count < center_number_length; count ++) {
1026                 dprintf("%c", message[14 + option_number_length + count]);
1027         }
1028         dprintf("\n");
1029
1030         /* Get message center related info if upper layer wants to know */
1031         if (data->MessageCenter) {
1032                 data->MessageCenter->Format = message[7];
1033                 data->MessageCenter->Validity = message[9];
1034
1035                 if (center_number_length == 0) {
1036                         data->MessageCenter->Number[0] = 0x00; /* Null terminate */
1037                 } else {
1038                         memcpy(data->MessageCenter->Number,
1039                                message + 14 + option_number_length,
1040                                center_number_length);
1041                         data->MessageCenter->Number[center_number_length] = '\0';
1042                 }
1043
1044                 /* 3810 series doesn't support Name or multiple center numbers
1045                    so put in null data for them . */
1046                 data->MessageCenter->Name[0] = 0x00;
1047                 data->MessageCenter->No = 0;
1048         }
1049
1050         /* Get SMS related info if upper layer wants to know */
1051         if (data->SMSStatus) {
1052                 data->SMSStatus->Unread = message[4] + message[6];
1053                 data->SMSStatus->Number = message[3] + message[5];
1054         }
1055
1056         /* Get memory info if upper layer wants to know */
1057         if (data->MemoryStatus) {
1058                 switch (data->MemoryStatus->MemoryType) {
1059                 case GMT_SM:
1060                         data->MemoryStatus->Used = message[5];
1061                         data->MemoryStatus->Free = P3110_MEMORY_SIZE_SM - message[5];
1062                         break;
1063                 case GMT_ME:
1064                         data->MemoryStatus->Used = message[3];
1065                         data->MemoryStatus->Free = P3110_MEMORY_SIZE_ME - message[3];
1066                         break;
1067                 default:
1068                         break;
1069                 }
1070         }
1071
1072         return GE_NONE;
1073 }
1074
1075
1076 /* 0x48 is sent during power-on of the phone, after the 0x13
1077    message is received and the PIN (if any) has been entered
1078    correctly. */
1079
1080 static GSM_Error P3110_IncomingPINEntered(int messagetype, unsigned char *message, int length, GSM_Data *data)
1081 {
1082         SimAvailable = true;
1083         dprintf("PIN [possibly] entered.\n");
1084         return GE_NONE;
1085 }
1086
1087
1088 /* 0x4b messages are sent by phone in response (it seems) to the keep 
1089    alive packet.  We must acknowledge these it seems by sending a 
1090    response with the "sequence number" byte loaded appropriately. */
1091
1092 static GSM_Error P3110_IncomingStatusInfo(int messagetype, unsigned char *message, int length, GSM_Data *data)
1093 {
1094         /* Strings for the status byte received from phone. */
1095         char *StatusStr[] = {
1096                 "Unknown",
1097                 "Ready",
1098                 "Interworking",
1099                 "Call in progress",
1100                 "No network access"
1101         };
1102
1103         /* There are three data bytes in the status message, two have been
1104            attributed to signal level, the third is presently unknown. 
1105            Unknown byte has been observed to be 0x01 when connected to normal
1106            network, 0x04 when no network available.   Steps through 0x02, 0x03
1107            when incoming or outgoing calls occur...*/   
1108         /*FB38_LinkOK = true;*/
1109
1110         /* Note: GetRFLevel function in fbus-3810.c does conversion 
1111            into required units. */
1112         if (data->RFLevel) {
1113                 *(data->RFUnits) = GRF_Arbitrary;
1114                 *(data->RFLevel) = message[3];
1115         }
1116
1117         /* Note: GetBatteryLevel function in fbus-3810.c does conversion 
1118            into required units. */
1119         if (data->BatteryLevel) { 
1120                 *(data->BatteryUnits) = GBU_Arbitrary;
1121                 *(data->BatteryLevel) = message[4];
1122         }
1123
1124         /* Only output connection status byte now as the RF and Battery
1125            levels are displayed by the main gnokii code. */
1126         dprintf("Status: %s, Battery level: %d, RF level: %d.\n",
1127                 StatusStr[message[2]], message[4], message[3]);
1128         return GE_NONE;
1129 }
1130
1131 /* 0x4d Message provides IMEI, Revision and Model information. */
1132
1133 static GSM_Error P3110_IncomingPhoneInfo(int messagetype, unsigned char *message, int length, GSM_Data *data)
1134 {
1135         size_t imei_length, rev_length, model_length;
1136
1137         imei_length = strlen(message + 2);
1138         rev_length = strlen(message + 3 + imei_length);
1139         model_length = strlen(message + 4 + imei_length + rev_length);
1140
1141         if (data->Imei)
1142                 strcpy(data->Imei, message + 2);
1143
1144         if (data->Revision)
1145                 strcpy(data->Revision, message + 3 + imei_length);
1146
1147         if (data->Model)
1148                 strcpy(data->Model, message + 4 + imei_length + rev_length);
1149
1150         dprintf("Mobile Phone Identification:\n");
1151         dprintf("   IMEI: %s\n", message + 2);
1152         dprintf("   Model: %s\n", message + 4 + imei_length + rev_length);
1153         dprintf("   Revision: %s\n", message + 3 + imei_length);
1154
1155         return GE_NONE;
1156 }
1157
1158
1159 /*
1160  */
1161
1162 void P3110_KeepAliveLoop(GSM_Statemachine *state)
1163 {
1164         GSM_Data data;
1165         GSM_DataClear(&data);
1166
1167         while (!RequestTerminate) {
1168
1169                 if (KeepAliveTimer == 0) {
1170                         KeepAliveTimer = P3110_KEEPALIVE_TIMEOUT;
1171                         /* Dont send keepalive packets when statemachine
1172                            is doing other transactions. */
1173                         if (state->CurrentState == Initialised) {
1174                                 dprintf("Sending keepalive message.\n");
1175                                 P3110_GetStatusInfo(&data, state);
1176                         }
1177                 } else {
1178                         KeepAliveTimer--;
1179                 }
1180                 usleep(100000); /* Avoid becoming a "busy" loop. */
1181         }
1182 }
1183
1184 void P3110_DecodeTime(unsigned char *b, GSM_DateTime *dt)
1185 {
1186         dt->Year = P3110_bcd2int(b[0]);
1187         dt->Month = P3110_bcd2int(b[1]);
1188         dt->Day = P3110_bcd2int(b[2]);
1189         dt->Hour = P3110_bcd2int(b[3]);
1190         dt->Minute = P3110_bcd2int(b[4]);
1191         dt->Second = P3110_bcd2int(b[5]);
1192         dt->Timezone = P3110_bcd2int(b[6]);
1193         return;
1194 }
1195
1196 int P3110_bcd2int(u8 x)
1197 {
1198         return (int)(10 * ((x & 0x0f)) + (x >> 4));
1199 }