24 #include "syncml_internals.h"
25 #include "sml_notification_internals.h"
26 #include "sml_transport_internals.h"
27 #include "sml_command_internals.h"
28 #include "sml_manager_internals.h"
29 #include "sml_error_internals.h"
30 #include "objects/sml_auth_internals.h"
31 #include "sml_elements_internals.h"
33 SmlNotification *smlNotificationNew(SmlNotificationVersion version, SmlNotificationUIMode mode, SmlNotificationInitiator init,
unsigned int sessionID,
const char *identifier,
const char *target, SmlMimeType type,
SmlError **error)
35 smlTrace(TRACE_ENTRY,
"%s(%i, %i, %i, %i, %s, %s, %i, %p)", __func__, version, mode, init, sessionID, VA_STRING(identifier), VA_STRING(target), type, error);
42 san->version = version;
45 san->sessionID = sessionID;
46 san->identifier = g_strdup(identifier);
49 san->sessionType = SML_SESSION_TYPE_SERVER;
52 san->target = smlLocationNew(target, NULL, error);
56 smlTrace(TRACE_EXIT,
"%s: %p", __func__, san);
68 smlTrace(TRACE_ENTRY,
"%s", __func__);
72 smlCredUnref(san->cred);
79 san->sessionType = SML_SESSION_TYPE_CLIENT;
81 smlTrace(TRACE_EXIT,
"%s", __func__);
86 smlTrace(TRACE_ENTRY,
"%s", __func__);
89 san->manager = manager;
90 smlTrace(TRACE_EXIT,
"%s", __func__);
95 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, san);
100 san->alerts = g_list_remove(san->alerts, alert);
101 smlNotificationFreeAlert(alert);
105 smlLocationUnref(san->target);
110 smlCredUnref(san->cred);
115 smlSafeCFree(&(san->identifier));
116 smlSafeFree((gpointer *)&san);
118 smlTrace(TRACE_EXIT,
"%s", __func__);
121 SmlBool smlNotificationNewAlert(
SmlNotification *san, SmlAlertType type,
const char *contenttype,
const char *serverURI,
SmlError **error)
123 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, error);
125 smlAssert(type >= 206 && type <= 210);
132 alert->contenttype = g_strdup(contenttype);
133 alert->serverURI = g_strdup(serverURI);
135 san->alerts = g_list_append(san->alerts, alert);
137 smlTrace(TRACE_EXIT,
"%s: %p", __func__, alert);
147 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, alert);
150 smlSafeCFree(&(alert->contenttype));
151 smlSafeCFree(&(alert->serverURI));
152 smlSafeFree((gpointer *)&alert);
154 smlTrace(TRACE_EXIT,
"%s", __func__);
159 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %p)", __func__, data, size, error);
165 smlErrorSet(error, SML_ERROR_GENERIC,
"Size too small");
169 unsigned int idLength = (uint8_t)data[23];
170 if (size < (25 + idLength)) {
171 smlErrorSet(error, SML_ERROR_GENERIC,
"Size too small2");
178 san->type = SML_MIMETYPE_SAN;
181 unsigned int version = ((uint8_t)data[16]) << 2;
182 version = version | ((uint8_t)data[17]) >> 6;
185 san->version = SML_SAN_VERSION_12;
188 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown version");
193 san->mode = (((uint8_t)data[17]) & 0x30) >> 4;
196 san->init = (((uint8_t)data[17]) & 0x08) >> 3;
199 san->sessionID = ((uint8_t)data[21]) << 8;
200 san->sessionID = san->sessionID | (uint8_t)data[22];
206 if (!san->identifier)
209 memcpy(san->identifier, data + 24, idLength);
212 unsigned int numSync = ((uint8_t)data[24 + idLength]) >> 4;
213 data += 25 + idLength;
214 unsigned int alertLength = 25 + idLength;
217 for (i = 0; i < numSync; i++) {
218 if (size < alertLength + 5) {
219 smlErrorSet(error, SML_ERROR_GENERIC,
"Size too small3");
223 idLength = (uint8_t)data[4];
224 if (size < (alertLength + 5 + idLength)) {
225 smlErrorSet(error, SML_ERROR_GENERIC,
"Size too small4");
228 alertLength = alertLength + 5 + idLength;
231 SmlAlertType alert_type = (((uint8_t)data[0]) >> 4) + 200;
232 if (alert_type < 206 || alert_type > 210) {
233 smlErrorSet(error, SML_ERROR_GENERIC,
"Wrong alert type");
237 unsigned int contenttype = ((uint8_t)data[1]) << 16;
238 contenttype = contenttype | ((uint8_t)data[2]) << 8;
239 contenttype = contenttype | ((uint8_t)data[3]);
242 const char *alert_ct;
243 switch (contenttype) {
252 alert_ct = SML_ELEMENT_TEXT_VCARD;
255 alert_ct = SML_ELEMENT_TEXT_VCAL;
258 alert_ct = SML_ELEMENT_TEXT_PLAIN;
261 alert_ct = SML_ELEMENT_TEXT_ICAL;
264 alert_ct = SML_ELEMENT_APPLICATION_OMA_DS_EMAIL;
267 alert_ct = SML_ELEMENT_APPLICATION_OMA_DS_FILE;
270 alert_ct = SML_ELEMENT_APPLICATION_OMA_DS_FOLDER;
273 alert_ct = SML_ELEMENT_TEXT_VCARD_30;
277 smlErrorSet(error, SML_ERROR_GENERIC,
"The OMNA WSP Content Type Number 0x%xd is not supported.", contenttype);
289 memcpy(alert_uri, data + 5, idLength);
291 data += 5 + idLength;
294 if (!smlNotificationNewAlert(san, alert_type, alert_ct, alert_uri, error))
299 smlSafeCFree(&alert_uri);
302 if (size > alertLength) {
303 smlErrorSet(error, SML_ERROR_GENERIC,
"Extra chunk at the end of the buffer");
307 smlTrace(TRACE_EXIT,
"%s: %p", __func__, san);
311 while (san->alerts) {
312 smlNotificationFreeAlert(san->alerts->data);
313 san->alerts = g_list_delete_link(san->alerts, san->alerts);
316 smlSafeCFree(&(san->identifier));
317 smlSafeFree((gpointer *)&san);
323 SmlBool smlNotificationAssemble11(
SmlNotification *san,
char **data,
unsigned int *size, SmlProtocolVersion version,
SmlError **error)
325 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %i, %p)", __func__, san, data, size, version, error);
335 smlAssert(san->manager);
343 source = smlLocationNew(san->identifier, NULL, error);
347 char *sessionString = smlManagerGetNewSessionID(san->manager);
348 session =
smlSessionNew(san->sessionType, san->type, version, SML_PROTOCOL_SYNCML, san->target, source, sessionString, 0, error);
350 smlSafeCFree(&sessionString);
351 smlLocationUnref(source);
354 smlSafeCFree(&sessionString);
355 smlManagerSessionAdd(san->manager, session, NULL, error);
369 for (a = san->alerts; a; a = a->next) {
373 SmlLocation *loc = smlLocationNew(alert->serverURI, NULL, error);
377 cmd = smlCommandNewAlert(SML_ALERT_TWO_WAY_BY_SERVER, NULL, loc, NULL, NULL, alert->contenttype, error);
379 smlLocationUnref(loc);
392 smlLocationUnref(loc);
394 smlCommandUnref(cmd);
402 smlSessionUnref(session);
404 smlLocationUnref(source);
409 smlTrace(TRACE_INTERNAL,
"San packet assembled: %s", hex);
412 smlTrace(TRACE_EXIT,
"%s", __func__);
417 smlCommandUnref(cmd);
419 smlSessionUnref(session);
428 static SmlBool _smlNotificationAssemble12(
SmlNotification *san,
char **data,
unsigned int *size,
SmlError **error)
430 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %p)", __func__, san, data, size, error);
434 smlAssert(*data == NULL);
436 unsigned int numsync = 0;
440 unsigned int length = 16 + 8 + strlen(san->identifier) + 1 ;
442 for (a = san->alerts; a; a = a->next) {
444 length += 5 + strlen(alert->serverURI);
462 buffer[17] = buffer[17] | (san->mode << 4);
465 buffer[17] = buffer[17] | (san->init << 3);
470 buffer[21] = san->sessionID >> 8;
471 buffer[22] = san->sessionID;
474 buffer[23] = strlen(san->identifier);
475 strncpy(buffer + 24, san->identifier, strlen(san->identifier));
477 buffer += 24 + strlen(san->identifier);
480 buffer[0] = numsync << 4;
483 for (a = san->alerts; a; a = a->next) {
486 buffer[0] = (alert->type - 200) << 4;
489 if (!strcmp(alert->contenttype, SML_ELEMENT_TEXT_VCARD)) {
491 }
else if (!strcmp(alert->contenttype, SML_ELEMENT_TEXT_VCAL)) {
493 }
else if (!strcmp(alert->contenttype, SML_ELEMENT_TEXT_PLAIN)) {
495 }
else if (!strcmp(alert->contenttype, SML_ELEMENT_TEXT_ICAL)) {
498 }
else if (!strcmp(alert->contenttype, SML_ELEMENT_APPLICATION_OMA_DS_EMAIL)) {
501 }
else if (!strcmp(alert->contenttype, SML_ELEMENT_APPLICATION_OMA_DS_FILE)) {
504 }
else if (!strcmp(alert->contenttype, SML_ELEMENT_APPLICATION_OMA_DS_FOLDER)) {
507 }
else if (!strcmp(alert->contenttype, SML_ELEMENT_TEXT_VCARD_30)) {
513 "%s: The OMNA WSP Content Type Number is unknown for %s.",
514 __func__, alert->contenttype);
519 buffer[4] = strlen(alert->serverURI);
520 strncpy(buffer + 5, alert->serverURI, strlen(alert->serverURI));
521 buffer += 5 + strlen(alert->serverURI);
531 unsigned char digest[16];
532 smlMD5GetDigest (*data+16, length - 16 , digest);
533 char *b64_san = g_base64_encode(digest, 16);
534 smlTrace(TRACE_INTERNAL,
"%s: b64(md5(san)) ::= %s", __func__, b64_san);
537 const char *username =
"";
538 const char *password =
"";
540 username = san->cred->username;
541 password = san->cred->password;
543 char *auth = g_strdup_printf(
"%s:%s", username, password);
544 smlMD5GetDigest (auth, strlen(auth), digest);
546 char *b64_auth = g_base64_encode(digest, 16);
547 smlTrace(TRACE_INTERNAL,
"%s: b64(md5(username:password)) ::= %s", __func__, b64_auth);
550 char *complete = g_strdup_printf(
"%s::%s", b64_auth, b64_san);
551 smlSafeCFree(&b64_auth);
552 smlSafeCFree(&b64_san);
553 smlMD5GetDigest (complete, strlen(complete), digest);
554 smlSafeCFree(&complete);
555 smlTrace(TRACE_INTERNAL,
"%s: md5(auth::san) complete", __func__);
558 memcpy(*data, digest, 16);
559 smlTrace(TRACE_INTERNAL,
"%s: md5(auth::san) copied to san", __func__);
564 smlTrace(TRACE_INTERNAL,
"San packet assembled: %s", hex);
567 smlTrace(TRACE_EXIT,
"%s", __func__);
581 switch (san->version) {
582 case SML_SAN_VERSION_12:
583 return _smlNotificationAssemble12(san, data, size, error);
584 case SML_SAN_VERSION_10:
585 return smlNotificationAssemble11(san, data, size, SML_VERSION_10, error);
586 case SML_SAN_VERSION_11:
587 return smlNotificationAssemble11(san, data, size, SML_VERSION_11, error);
588 case SML_SAN_VERSION_UNKNOWN:
589 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown SAN version.");
598 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, san, tsp, error);
604 unsigned int size = 0;
605 if (!smlNotificationAssemble(san, &data, &size, error))
609 if (san->version == SML_SAN_VERSION_12)
610 tspdata = smlTransportDataNew(data, size, SML_MIMETYPE_SAN, TRUE, error);
612 tspdata = smlTransportDataNew(data, size, san->type, TRUE, error);
615 goto error_free_data;
622 if (san->version == SML_SAN_VERSION_12)
625 if (!smlTransportSend(tsp, NULL, tspdata, error))
626 goto error_free_tspdata;
628 smlTransportDataDeref(tspdata);
630 smlTrace(TRACE_EXIT,
"%s", __func__);
634 smlTransportDataDeref(tspdata);
654 SmlNotificationInitiator smlNotificationGetInitiator(
SmlNotification *san)
663 return san->sessionID;
669 return san->identifier;
675 return g_list_length(san->alerts);
681 return g_list_nth_data(san->alerts, nth);
684 SmlAlertType smlSanAlertGetType(
SmlSanAlert *alert)
690 const char *smlSanAlertGetContentType(
SmlSanAlert *alert)
693 return alert->contenttype;
695 const char *smlSanAlertGetServerURI(
SmlSanAlert *alert)
698 return alert->serverURI;
SmlBool smlAssemblerAddHeader(SmlAssembler *assm, SmlSession *session, SmlError **error)
Assembles the header.
const char * smlErrorPrint(SmlError **error)
Returns the message of the error.
char * smlPrintHex(const char *data, int len)
Used for printing binary data in just hex.
SmlAssemblerResult smlAssemblerStartCommand(SmlAssembler *assm, SmlCommand *parent, SmlCommand *cmd, SmlError **error)
Starts a parent command.
SmlBool smlAssemblerRun(SmlAssembler *assm, char **data, unsigned int *size, SmlBool *end, SmlBool final, SmlError **error)
Assembles the complete message and returns the result.
unsigned int smlAssemblerFlush(SmlAssembler *assm)
Flushes the already parsed commands.
SmlBool smlAssemblerStart(SmlAssembler *assm, SmlSession *session, SmlError **error)
Starts a new message.
void smlTrace(SmlTraceType type, const char *message,...)
Used for tracing the application.
void smlAssemblerFree(SmlAssembler *assm)
Frees a assembler.
SmlBool smlAssemblerEndCommand(SmlAssembler *assm, SmlCommand *parent, SmlError **error)
Ends a parent command.
SmlAssembler * smlAssemblerNew(SmlMimeType type, unsigned int limit, SmlError **error)
Creates a new assembler.
SmlSession * smlSessionNew(SmlSessionType sessionType, SmlMimeType mimetype, SmlProtocolVersion version, SmlProtocolType protocol, SmlLocation *target, SmlLocation *source, const char *sessionID, unsigned int messageID, SmlError **error)
Creates a new session.
void * smlTryMalloc0(long n_bytes, SmlError **error)
Safely mallocs.
void smlErrorSet(SmlError **error, SmlErrorType type, const char *format,...)
Sets the error.