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