and 6110.
$Log$
- Revision 1.1.1.1 2001/11/25 21:59:03 short
- :pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Sun Nov 25 22:56 CET 2001
+ Revision 1.1.1.2 2002/04/03 00:07:54 short
+ Found in "gnokii-working" directory, some November-patches version
Revision 1.136 2001/08/20 23:27:37 pkot
Add hardware shakehand to the link layer (Manfred Jonsson)
FB61_GetBitmap,
FB61_SetBitmap,
FB61_SetRingTone,
- FB61_SendRingTone,
FB61_Reset,
FB61_GetProfile,
FB61_SetProfile,
14, 72 /* Caller logo size */
};
-unsigned char GSM_Default_Alphabet[] = {
-
- /* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */
- /* Characters in hex position 10, [12 to 1a] and 24 are not present on
- latin1 charset, so we cannot reproduce on the screen, however they are
- greek symbol not present even on my Nokia */
-
- '@', 0xa3, '$', 0xa5, 0xe8, 0xe9, 0xf9, 0xec,
- 0xf2, 0xc7, '\n', 0xd8, 0xf8, '\r', 0xc5, 0xe5,
- '?', '_', '?', '?', '?', '?', '?', '?',
- '?', '?', '?', '?', 0xc6, 0xe6, 0xdf, 0xc9,
- ' ', '!', '\"', '#', 0xa4, '%', '&', '\'',
- '(', ')', '*', '+', ',', '-', '.', '/',
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', ':', ';', '<', '=', '>', '?',
- 0xa1, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
- 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
- 'X', 'Y', 'Z', 0xc4, 0xd6, 0xd1, 0xdc, 0xa7,
- 0xbf, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
- 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
- 'x', 'y', 'z', 0xe4, 0xf6, 0xf1, 0xfc, 0xe0
-};
-
const char *FB61_MemoryType_String [] = {
"", /* 0x00 */
"MT", /* 0x01 */
static GSM_SMSMessage *CurrentSMSMessage;
static GSM_Error CurrentSMSMessageError;
-static int CurrentSMSPointer;
static GSM_MemoryStatus *CurrentMemoryStatus;
static GSM_Error CurrentMemoryStatusError;
#endif
}
-#define ByteMask ((1 << Bits) - 1)
-
-int UnpackEightBitsToSeven(int offset, int in_length, int out_length,
- unsigned char *input, unsigned char *output)
-{
- unsigned char *OUT = output; /* Current pointer to the output buffer */
- unsigned char *IN = input; /* Current pointer to the input buffer */
- unsigned char Rest = 0x00;
- int Bits;
-
- Bits = offset ? offset : 7;
-
- while ((IN - input) < in_length) {
-
- *OUT = ((*IN & ByteMask) << (7 - Bits)) | Rest;
- Rest = *IN >> Bits;
-
- /* If we don't start from 0th bit, we shouldn't go to the
- next char. Under *OUT we have now 0 and under Rest -
- _first_ part of the char. */
- if ((IN != input) || (Bits == 7)) OUT++;
- IN++;
-
- if ((OUT - output) >= out_length) break;
-
- /* After reading 7 octets we have read 7 full characters but
- we have 7 bits as well. This is the next character */
- if (Bits == 1) {
- *OUT = Rest;
- OUT++;
- Bits = 7;
- Rest = 0x00;
- } else {
- Bits--;
- }
- }
-
- return OUT - output;
-}
-
-unsigned char GetAlphabetValue(unsigned char value)
-{
- unsigned char i;
-
- if (value == '?') return 0x3f;
-
- for (i = 0 ; i < 128 ; i++)
- if (GSM_Default_Alphabet[i] == value)
- return i;
-
- return 0x3f; /* '?' */
-}
-
-int PackSevenBitsToEight(int offset, unsigned char *input, unsigned char *output)
-{
- unsigned char *OUT = output; /* Current pointer to the output buffer */
- unsigned char *IN = input; /* Current pointer to the input buffer */
- int Bits; /* Number of bits directly copied to
- the output buffer */
- Bits = (7 + offset) % 8;
-
- /* If we don't begin with 0th bit, we will write only a part of the
- first octet */
- if (offset) {
- *OUT = 0x00;
- OUT++;
- }
-
- while ((IN - input) < strlen(input)) {
- unsigned char Byte = GetAlphabetValue(*IN);
-
- *OUT = Byte >> (7 - Bits);
- /* If we don't write at 0th bit of the octet, we should write
- a second part of the previous octet */
- if (Bits != 7)
- *(OUT-1) |= (Byte & ((1 << (7-Bits)) - 1)) << (Bits+1);
-
- Bits--;
-
- if (Bits == -1) Bits = 7;
- else OUT++;
-
- IN++;
- }
- return (OUT - output);
-}
-
GSM_Error FB61_GetRFLevel(GSM_RFUnits *units, float *level)
{
/* FIXME - these values are from 3810 code, may be incorrect. Map from
return wait_on(&CurrentSMSMessageError, 50);
}
-/* This function implements packing of numbers (SMS Center number and
- destination number) for SMS sending function. */
-
-int SemiOctetPack(char *Number, unsigned char *Output)
-{
- unsigned char *IN = Number; /* Pointer to the input number */
- unsigned char *OUT = Output; /* Pointer to the output */
- int count = 0; /* This variable is used to notify us about count of already
- packed numbers. */
-
- /* The first byte in the Semi-octet representation of the address field is
- the Type-of-Address. This field is described in the official GSM
- specification 03.40 version 5.3.0, section 9.1.2.5, page 33. We support
- only international and unknown number. */
-
- if (*IN == '+') {
- *OUT++ = GNT_INTERNATIONAL; /* International number */
- IN++;
- } else *OUT++ = GNT_UNKNOWN; /* Unknown number */
-
- /* The next field is the number. It is in semi-octet representation - see
- GSM scpecification 03.40 version 5.3.0, section 9.1.2.3, page 31. */
-
- while (*IN) {
- if (count & 0x01) {
- *OUT = *OUT | ((*IN - '0') << 4);
- OUT++;
- }
- else
- *OUT = *IN - '0';
- count++; IN++;
- }
-
- /* We should also fill in the most significant bits of the last byte with
- 0x0f (1111 binary) if the number is represented with odd number of
- digits. */
-
- if (count & 0x01) {
- *OUT=*OUT | 0xf0;
- OUT++;
- return (2 * (OUT - Output - 1) - 1);
- }
-
- return (2 * (OUT - Output - 1));
-}
-
/* The second argument is the size of the data in octets,
excluding User Data Header - important only for 8bit data */
-GSM_Error FB61_SendSMSMessage(GSM_SMSMessage *SMS, int data_size)
+GSM_Error FB61_SendSMSMessage(GSM_SMSMessage *SMS)
{
GSM_Error error;
}
dprintf(_("Sending SMS to %s via message center %s\n"), SMS->Destination, SMS->MessageCenter.Number);
- if (SMS->UDHType) {
+ if (SMS->UDHPresent) {
/* offset - length of the user data header */
offset = 1 + SMS->UDH[0];
/* we copy the udh and set the mask for the indicator */
}
/* size is the length of the data in octets including udh */
- /* SMS->Length is:
+ /* req[22] is:
- integer representation of the number od octets within the user data when UD is coded using 8bit data
- the sum of the number of septets in UDH including any padding and number of septets in UD in other case
*/
+
+ size = offset;
/* offset now denotes UDH length */
if (SMS->EightBit) {
- memcpy(req + 42 + offset, SMS->MessageText, data_size);
- SMS->Length = size = data_size + offset;
+ memcpy(req + 42 + offset, SMS->MessageText, SMS->MessageTextLength);
/* the mask for the 8-bit data */
req[21] |= 0xf4;
+ size += SMS->MessageTextLength;
+ req[22] = size;
} else {
- size = PackSevenBitsToEight((7-offset)%7, SMS->MessageText, req + 42 + offset);
- size += offset;
- SMS->Length = (offset*8 + ((7-offset)%7)) / 7 + strlen(SMS->MessageText);
+ size += PackSevenBitsToEight((7-offset)%7, SMS->MessageText, req + 42 + offset);
+ req[22] = (offset*8 +6/*round-up*/)/7 +strlen(SMS->MessageText)*7;
}
- req[22] = SMS->Length;
-
CurrentSMSMessageError=GE_BUSY;
req[6] = SemiOctetPack(SMS->MessageCenter.Number, req+7);
req[23] = SemiOctetPack(SMS->Destination, req+24);
/* TP-Validity Period handling */
-
- /* FIXME: error-checking for correct Validity - it should not be bigger then
- 63 weeks and smaller then 5minutes. We should also test intervals because
- the SMS->Validity to TP-VP is not continuos. I think that the simplest
- solution will be an array of correct values. We should parse it and if we
- find the closest TP-VP value we should use it. Or is it good to take
- closest smaller TP-VP as we do now? I think it is :-) */
-
- /* 5 minutes intervals up to 12 hours = 720 minutes */
- if (SMS->Validity <= 720)
- req[35] = (unsigned char) (SMS->Validity/5)-1;
-
- /* 30 minutes intervals up to 1 day */
- else if ((SMS->Validity > 720) && (SMS->Validity <= 1440))
- req[35] = (unsigned char) ((SMS->Validity-720)/30)+143;
-
- /* 1 day intervals up to 30 days */
- else if ((SMS->Validity > 1440) && (SMS->Validity <= 43200))
- req[35] = (unsigned char) (SMS->Validity/1440)+166;
-
- /* 1 week intervals up to 63 weeks */
- else if ((SMS->Validity > 43200) && (SMS->Validity <= 635040))
- req[35] = (unsigned char) (SMS->Validity/10080)+192;
+ req[35] = SMS_Validity_to_VP(SMS->Validity);
FB61_TX_SendMessage(42+size, 0x02, req);
return wait_on(&CurrentSMSMessageError, 70);
}
+/* FIXME: UDH & EightBit not implemented yet */
GSM_Error FB61_SaveSMSMessage(GSM_SMSMessage *SMS)
{
unsigned char req[256] = {
return(GE_SMSTOOLONG);
/* size is the length of the data in octets including udh */
- /* SMS->Length is:
+ /* req[24] is:
- integer representation of the number od octets within the user data when UD is coded using 8bit data
- the sum of the number of septets in UDH including any padding and number of septets in UD in other case
*/
/* offset now denotes UDH length */
size = PackSevenBitsToEight((7-offset)%7, SMS->MessageText, req + 44 + offset);
size += offset;
- SMS->Length = (offset*8 + ((7-offset)%7)) / 7 + strlen(SMS->MessageText);
- req[24] = SMS->Length;
+ req[24] = (offset*8 + ((7-offset)%7)) / 7 + strlen(SMS->MessageText);
+
FB61_TX_SendMessage(44+size, 0x14, req);
return wait_on(&CurrentSMSMessageError, 70);
}
return (GE_NONE);
}
-GSM_Error FB61_SendRingTone(GSM_Ringtone *ringtone, char *dest)
-{
- GSM_SMSMessage SMS;
- GSM_Error error;
-
- int size = GSM_MAX_RINGTONE_PACKAGE_LENGTH;
- char Package[GSM_MAX_RINGTONE_PACKAGE_LENGTH];
- char udh[] = {
- 0x06, /* User Data Header Length */
- 0x05, /* IEI */
- 0x04, /* IEDL */
- 0x15, 0x81, /* Destination port */
- 0x15, 0x81 /* Originator port, only
- to fill in the two
- bytes :-) */
- };
-
- /* Default settings for SMS message:
- - no delivery report
- - Class Message 1
- - no compression
- - 8 bit data
- - SMSC no. 1
- - validity 3 days
- - set UserDataHeaderIndicator
- */
-
- SMS.Type = GST_MO;
- SMS.Class = 1;
- SMS.Compression = false;
- SMS.EightBit = true;
- SMS.MessageCenter.No = 1;
- SMS.Validity = 4320; /* 4320 minutes == 72 hours */
-
- SMS.UDHType = GSM_RingtoneUDH;
-
- strcpy(SMS.Destination, dest);
- GSM_PackRingtone(ringtone, Package, &size);
- memcpy(SMS.UDH, udh, 7);
- memcpy(SMS.MessageText, Package, size);
-
- /* Send the message. */
- error = FB61_SendSMSMessage(&SMS, size);
-
- if (error == GE_SMSSENDOK) dprintf(_("Send succeeded!\n"));
- else dprintf(_("SMS Send failed (error=%d)\n"), error);
-
- return (GE_NONE);
-}
-
GSM_Error FB61_Reset(unsigned char type)
{
unsigned char req[4] = { 0x00,0x01,0x64,0x03 };
}
#endif /* WIN32 */
-char *FB61_GetBCDNumber(u8 *Number)
-{
- static char Buffer[20] = "";
-
- /* This is the length of BCD coded number */
- int length = Number[0];
- int count;
-
- if (Number[1] == 0x91) sprintf(Buffer, "+");
- else Buffer[0] = '\0';
-
- for (count = 0; count < length-1; count++) {
- int Digit;
- Digit = Number[count+2] & 0x0f;
- if (Digit < 10) sprintf(Buffer, "%s%d", Buffer, Digit);
- Digit = Number[count+2] >> 4;
- if (Digit < 10) sprintf(Buffer, "%s%d", Buffer, Digit);
- }
-
- return Buffer;
-}
-
char *FB61_GetPackedDateTime(u8 *Number)
{
static char Buffer[20] = "";
case 0x10:
dprintf(_("Message: SMS Message Received\n"));
- dprintf(_(" SMS center number: %s\n"), FB61_GetBCDNumber(MessageBuffer+7));
+ dprintf(_(" SMS center number: %s\n"), SEMIOCTETUNPACK_STATIC_BYTES(MessageBuffer+7));
MessageBuffer[23] = (MessageBuffer[23]+1)/2+1;
- dprintf(_(" Remote number: %s\n"), FB61_GetBCDNumber(MessageBuffer+23));
+ dprintf(_(" Remote number: %s\n"), SEMIOCTETUNPACK_STATIC_BYTES(MessageBuffer+23));
dprintf(_(" Date: %s\n"), FB61_GetPackedDateTime(MessageBuffer+35));
dprintf(_(" SMS: "));
CurrentMessageCenter->Format = MessageBuffer[6];
CurrentMessageCenter->Validity = MessageBuffer[8];
sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
- sprintf(CurrentMessageCenter->Number, "%s", FB61_GetBCDNumber(MessageBuffer+21));
+ sprintf(CurrentMessageCenter->Number, "%s", SEMIOCTETUNPACK_STATIC_BYTES(MessageBuffer+21));
dprintf(_("Message: SMS Center received:\n"));
dprintf(_(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
CurrentSMSMessage->Status = GSS_SENTREAD;
off = 0;
- if (MessageBuffer[20] & 0x40) {
- switch (MessageBuffer[40+offset]) {
- case 0x00: /* concatenated messages */
- dprintf(_("Concatenated message!!!\n"));
- CurrentSMSMessage->UDHType = GSM_ConcatenatedMessages;
- if (MessageBuffer[41+offset] != 0x03) {
- /* should be some error */
- }
- break;
- case 0x05: /* logos */
- switch (MessageBuffer[43+offset]) {
- case 0x82:
- CurrentSMSMessage->UDHType = GSM_OpLogo;
- break;
- case 0x83:
- CurrentSMSMessage->UDHType = GSM_CallerIDLogo;
- break;
- }
- break;
- default:
- break;
- }
- /* Skip user data header when reading data */
- off = (MessageBuffer[39+offset] + 1);
- for (i = 0; i < off; i++)
- CurrentSMSMessage->UDH[i] = MessageBuffer[39+offset+i];
- } else {
- CurrentSMSMessage->UDHType = GSM_NoUDH;
- }
+ CurrentSMSMessage->UDHPresent=!!(MessageBuffer[20] & 0x40);
MessageBuffer[20+offset] = (MessageBuffer[20+offset]+1)/2+1;
}
dprintf("\n");
}
- dprintf(_(" SMS center number: %s\n"), FB61_GetBCDNumber(MessageBuffer + 8));
- dprintf(_(" Remote number: %s\n"), FB61_GetBCDNumber(MessageBuffer + 20 + offset));
+ dprintf(_(" SMS center number: %s\n"), SEMIOCTETUNPACK_STATIC_BYTES(MessageBuffer + 8));
+ dprintf(_(" Remote number: %s\n"), SEMIOCTETUNPACK_STATIC_BYTES(MessageBuffer + 20 + offset));
break;
}
CurrentSMSMessage->Time.Timezone = (10 * (MessageBuffer[38+offset] & 0x07) + (MessageBuffer[38+offset] >> 4)) / 4;
if (MessageBuffer[38+offset] & 0x08)
CurrentSMSMessage->Time.Timezone = -CurrentSMSMessage->Time.Timezone;
- strcpy(CurrentSMSMessage->Sender, FB61_GetBCDNumber(MessageBuffer + 20 + offset));
- strcpy(CurrentSMSMessage->MessageCenter.Number, FB61_GetBCDNumber(MessageBuffer + 8));
+ strcpy(CurrentSMSMessage->Sender, SEMIOCTETUNPACK_STATIC_BYTES(MessageBuffer + 20 + offset));
+ strcpy(CurrentSMSMessage->MessageCenter.Number, SEMIOCTETUNPACK_STATIC_BYTES(MessageBuffer + 8));
}
if (CurrentSMSMessage->Type != GST_DR) {
/* 8bit SMS */
if ((MessageBuffer[18+offset] & 0xf4) == 0xf4) {
CurrentSMSMessage->EightBit = true;
- tmp=CurrentSMSMessage->Length=MessageBuffer[19+offset];
+ tmp=MessageBuffer[19+offset];
offset += off;
memcpy(output, MessageBuffer - 39 - offset - 2, tmp - offset);
/* 7bit SMS */
} else {
CurrentSMSMessage->EightBit = false;
- CurrentSMSMessage->Length=MessageBuffer[19+offset] - (off * 8 + ((7-off)%7)) / 7;
+ tmp=MessageBuffer[19+offset] - (off * 8 + ((7-off)%7)) / 7;
offset += off;
- tmp=UnpackEightBitsToSeven((7-off)%7, MessageLength - 39 - offset - 2, CurrentSMSMessage->Length, MessageBuffer + 39 + offset, output);
+ tmp=UnpackEightBitsToSeven((7-off)%7, MessageLength - 39 - offset - 2, tmp, MessageBuffer + 39 + offset, output);
}
for (i = 0; i < tmp;i++) {
dprintf("%c", GSM_Default_Alphabet[output[i]]);
CurrentSMSMessage->MessageText[i] = GSM_Default_Alphabet[output[i]];
}
+ CurrentSMSMessage->MessageTextLength = tmp;
} else { /* CurrentSMSMessage->Type == GST_DR (Delivery Report) */
/* SMSC Response time */
CurrentSMSMessage->SMSCTime.Year = 10 * (MessageBuffer[39+offset] & 0x0f) + (MessageBuffer[39+offset] >> 4);
dprintf(_("SM replaced by the SC"));
break;
}
- CurrentSMSMessage->Length = tmp = 10;
} else if (MessageBuffer[22] & 0x40) {
strcpy(CurrentSMSMessage->MessageText, _("Failed"));
break;
}
}
- CurrentSMSMessage->Length = tmp = 6;
} else if (MessageBuffer[22] & 0x20) {
strcpy(CurrentSMSMessage->MessageText, _("Pending"));
dprintf(_("Reserved/Specific to SC: %x"), MessageBuffer[22]);
break;
}
- CurrentSMSMessage->Length = tmp = 7;
} else {
strcpy(CurrentSMSMessage->MessageText, _("Unknown"));
/* more detailed reason only for debug */
dprintf(_("Reserved/Specific to SC: %x"), MessageBuffer[22]);
- CurrentSMSMessage->Length = tmp = 8;
}
+ CurrentSMSMessage->MessageTextLength = strlen(CurrentSMSMessage->MessageText);
}
- CurrentSMSMessage->MessageText[CurrentSMSMessage->Length] = 0;
+ CurrentSMSMessage->MessageText[CurrentSMSMessage->MessageTextLength] = 0;
- CurrentSMSPointer = tmp;
-
CurrentSMSMessage->MemoryType = MessageBuffer[5];
CurrentSMSMessage->MessageNumber = MessageBuffer[6];
dprintf(_(" The number of messages: %d\n"), MessageBuffer[10]);
dprintf(_(" Unread messages: %d\n"), MessageBuffer[11]);
CurrentSMSStatus->UnRead = MessageBuffer[11];
- CurrentSMSStatus->Number = MessageBuffer[10];
+ CurrentSMSStatus->Used = MessageBuffer[10];
+ CurrentSMSStatus->Slots = CurrentSMSStatus->Used; /* is it correct? */
CurrentSMSStatusError = GE_NONE;
break;