Gammu internals  1.38.0
s60.c
Go to the documentation of this file.
1 /* This program is free software; you can redistribute it and/or modify
2  * it under the terms of the GNU General Public License as published by
3  * the Free Software Foundation; either version 2 of the License, or
4  * (at your option) any later version.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License along
12  * with this program; if not, write to the Free Software Foundation, Inc.,
13  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14  *
15  * Copyright (c) 2011 Michal Cihar <[email protected]>
16  */
17 
18 
19 #include "../../gsmstate.h"
20 
21 #if defined(GSM_ENABLE_S60)
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 
27 #include "../../gsmcomon.h"
28 #include "s60.h"
29 #include "s60-ids.h"
30 
31 static GSM_Error S60_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer,
32  int MsgLength, int MsgType)
33 {
34  unsigned char *buffer=NULL;
35  int pos, sent, length, buflen, bufpos;
36  GSM_Error error;
37 
38  /* No type */
39  if (MsgType == 0) {
40  return ERR_NONE;
41  }
42 
43  /* Allocate buffer for composing message */
44  buflen = MIN(MAX_LENGTH, MsgLength) + 10;
45  buffer = (unsigned char *)malloc(buflen);
46  if (buffer == NULL) {
47  return ERR_MOREMEMORY;
48  }
49 
50  /* Send message parts */
51  for (pos = 0; MsgLength - pos > MAX_LENGTH; pos += MAX_LENGTH) {
52  error = S60_WriteMessage(s, MsgBuffer + pos, MAX_LENGTH, NUM_PARTIAL_MESSAGE);
53  if (error != ERR_NONE) {
54  free(buffer);
55  return ERR_DEVICEWRITEERROR;
56  }
57  }
58 
59  /* Send final message */
60  buffer[0] = MsgType;
61  length = MsgLength - pos;
62 
63  bufpos = snprintf(buffer, buflen, "%d%c", MsgType, NUM_END_HEADER);
64  memcpy(buffer + bufpos, MsgBuffer + pos, length);
65  buffer[bufpos + length] = '\n';
66  length += bufpos + 1;
67 
68  /* Debugging */
69  GSM_DumpMessageBinary(s, buffer, length, MsgType);
70  GSM_DumpMessageText(s, buffer, length, MsgType);
71 
72  sent = s->Device.Functions->WriteDevice(s, buffer, length);
73  free(buffer);
74  if (sent != length) {
75  return ERR_DEVICEWRITEERROR;
76  }
77 
78  return ERR_NONE;
79 }
80 
81 static GSM_Error S60_StateMachine(GSM_StateMachine *s, unsigned char rxchar)
82 {
83  GSM_Protocol_S60Data *d = &s->Protocol.Data.S60;
84 
85  /* Did we complete part of packet? */
86  switch (d->State) {
87  case S60_Header:
88  if (rxchar == NUM_END_HEADER) {
89  d->Msg.Type = atoi(d->idbuffer);
90  d->State = S60_Data;
91  d->idpos = 0;
92  } else {
93  d->idbuffer[d->idpos++] = rxchar;
94  d->idbuffer[d->idpos] = 0;
95  }
96  break;
97  case S60_Data:
98  if (rxchar == NUM_END_TEXT) {
99  d->State = S60_Header;
100  /* Should we wait for other parts? */
101  if (d->Msg.Type == NUM_PARTIAL_MESSAGE) {
102  return ERR_NONE;
103  }
104 
105  /* We've got data to process */
106  s->Phone.Data.RequestMsg = &d->Msg;
108 
109  /* Reset message length */
110  d->Msg.Length = 0;
111  } else {
112  /* Allocate buffer */
113  if (d->Msg.BufferUsed < d->Msg.Length + 2) {
114  d->Msg.BufferUsed = d->Msg.Length + 2;
115  d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer, d->Msg.BufferUsed);
116  if (d->Msg.Buffer == NULL) {
117  return ERR_MOREMEMORY;
118  }
119  }
120 
121  /* Store received byte */
122  d->Msg.Buffer[d->Msg.Length++] = rxchar;
123  d->Msg.Buffer[d->Msg.Length] = 0;
124  }
125  break;
126  }
127 
128  return ERR_NONE;
129 }
130 
131 static GSM_Error S60_Initialise(GSM_StateMachine *s)
132 {
133  GSM_Protocol_S60Data *d = &s->Protocol.Data.S60;
134 
135  d->Msg.BufferUsed = 0;
136  d->Msg.Buffer = NULL;
137  d->Msg.Length = 0;
138  d->State = S60_Header;
139  d->idpos = 0;
140 
141  return ERR_NONE;
142 }
143 
144 static GSM_Error S60_Terminate(GSM_StateMachine *s)
145 {
146  free(s->Protocol.Data.S60.Msg.Buffer);
147  s->Protocol.Data.S60.Msg.Buffer = NULL;
148 
149  return ERR_NONE;
150 }
151 
152 GSM_Protocol_Functions S60Protocol = {
153  S60_WriteMessage,
154  S60_StateMachine,
155  S60_Initialise,
156  S60_Terminate
157 };
158 
159 #endif
160 
161 
162 /* How should editor hadle tabs in this file? Add editor commands here.
163  * vim: noexpandtab sw=8 ts=8 sts=8:
164  */
void GSM_DumpMessageBinary(GSM_StateMachine *s, unsigned const char *message, size_t messagesize, int type)
Definition: gsmstate.c:1583
char idbuffer[20]
Definition: s60.h:31
struct GSM_Protocol::@1 Data
GSM_Error
Definition: gammu-error.h:23
GSM_Error DispatchError
Definition: gsmstate.h:689
Definition: s60.h:24
int(* WriteDevice)(GSM_StateMachine *s, const void *buf, size_t nbytes)
Definition: gsmstate.h:256
S60_State State
Definition: s60.h:30
#define NUM_END_HEADER
Definition: s60-ids.h:98
GSM_Phone Phone
Definition: gsmstate.h:1431
#define NUM_END_TEXT
Definition: s60-ids.h:101
GSM_Device_Functions * Functions
Definition: gsmstate.h:335
GSM_Protocol Protocol
Definition: gsmstate.h:1430
GSM_Phone_Data Data
Definition: gsmstate.h:1369
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
#define NUM_PARTIAL_MESSAGE
Definition: s60-ids.h:10
GSM_Protocol_Message Msg
Definition: s60.h:29
#define MIN(a, b)
Definition: gammu-misc.h:70
GSM_Error(* DispatchMessage)(GSM_StateMachine *s)
Definition: gsmstate.h:765
Definition: s60.h:25
unsigned char * Buffer
Definition: protocol.h:22
#define MAX_LENGTH
Definition: s60-ids.h:4
GSM_Protocol_Message * RequestMsg
Definition: gsmstate.h:676
void GSM_DumpMessageText(GSM_StateMachine *s, unsigned const char *message, size_t messagesize, int type)
Definition: gsmstate.c:1555
GSM_Device Device
Definition: gsmstate.h:1429